Patchwork Initial shrink-wrapping patch

login
register
mail settings
Submitter Bernd Schmidt
Date Oct. 6, 2011, 9:39 p.m.
Message ID <4E8E2011.5070204@codesourcery.com>
Download mbox | patch
Permalink /patch/118170/
State New
Headers show

Comments

Bernd Schmidt - Oct. 6, 2011, 9:39 p.m.
On 10/06/11 21:33, Ian Lance Taylor wrote:

> Note that you can test Go yourself by adding --enable-languages=go to
> your configure line.  Nothing special is required to build Go.  It works
> better if you use the gold linker but that is not required.

Oh, ok. For some reason I thought I was remembering that it doesn't
build on my box.

Here's the set of fixes I have now. find_many_sub_blocks needs to be run
on the destination of the orig_entry_edge, and it also appears to munge
basic block pointers, so unconverted_simple_returns now stores jump
insns. For HJ's problem I gave in and used register numbers rather than
comparing with stack_pointer_rtx etc., and converted some more code to
use df as originally suggested by Richard S.

Testing now with rth's csa patch also applied, both i686-linux and
x86_64-linux. Bootstraps complete, all languages including Go for the
i686-linux one. Ok if testing passes?


Bernd
* function.c (frame_required_for_rtx): Remove function.
	(requires_stack_frame_p): New arg set_up_by_prologue.  All callers
	changed.  Compute a set of mentioned registers and compare against
	the new arg rather than calling frame_required_for_rtx.
	(thread_prologue_and_epilogue_insns): Compute the set_up_by_prologue
	reg set.  Convert the unconverted_simple_returns mechanism to store
	jump insns rather than their basic blocks.  Also check the
	orig_entry_edge destination for new blocks.
Richard Henderson - Oct. 6, 2011, 10:18 p.m.
On 10/06/2011 02:39 PM, Bernd Schmidt wrote:
> 	* function.c (frame_required_for_rtx): Remove function.
> 	(requires_stack_frame_p): New arg set_up_by_prologue.  All callers
> 	changed.  Compute a set of mentioned registers and compare against
> 	the new arg rather than calling frame_required_for_rtx.
> 	(thread_prologue_and_epilogue_insns): Compute the set_up_by_prologue
> 	reg set.  Convert the unconverted_simple_returns mechanism to store
> 	jump insns rather than their basic blocks.  Also check the
> 	orig_entry_edge destination for new blocks.

Ok.


r~

Patch

Index: function.c
===================================================================
--- function.c	(revision 179627)
+++ function.c	(working copy)
@@ -5303,25 +5303,15 @@  record_hard_reg_uses (rtx *px, void *dat
   for_each_rtx (px, record_hard_reg_uses_1, data);
 }
 
-/* A subroutine of requires_stack_frame_p, called via for_each_rtx.
-   Return 1 if we found an rtx that forces a prologue, zero otherwise.  */
-static int
-frame_required_for_rtx (rtx *loc, void *data ATTRIBUTE_UNUSED)
-{
-  rtx x = *loc;
-  if (x == stack_pointer_rtx || x == hard_frame_pointer_rtx
-      || x == arg_pointer_rtx || x == pic_offset_table_rtx)
-    return 1;
-  return 0;
-}
-
 /* Return true if INSN requires the stack frame to be set up.
    PROLOGUE_USED contains the hard registers used in the function
-   prologue.  */
+   prologue.  SET_UP_BY_PROLOGUE is the set of registers we expect the
+   prologue to set up for the function.  */
 static bool
-requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used)
+requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used,
+			HARD_REG_SET set_up_by_prologue)
 {
-  df_ref *def_rec;
+  df_ref *df_rec;
   HARD_REG_SET hardregs;
   unsigned regno;
 
@@ -5329,13 +5319,11 @@  requires_stack_frame_p (rtx insn, HARD_R
     return false;
   if (CALL_P (insn))
     return !SIBLING_CALL_P (insn);
-  if (for_each_rtx (&PATTERN (insn), frame_required_for_rtx, NULL))
-    return true;
 
   CLEAR_HARD_REG_SET (hardregs);
-  for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
+  for (df_rec = DF_INSN_DEFS (insn); *df_rec; df_rec++)
     {
-      rtx dreg = DF_REF_REG (*def_rec);
+      rtx dreg = DF_REF_REG (*df_rec);
 
       if (!REG_P (dreg))
 	continue;
@@ -5350,6 +5338,20 @@  requires_stack_frame_p (rtx insn, HARD_R
     if (TEST_HARD_REG_BIT (hardregs, regno)
 	&& df_regs_ever_live_p (regno))
       return true;
+
+  for (df_rec = DF_INSN_USES (insn); *df_rec; df_rec++)
+    {
+      rtx reg = DF_REF_REG (*df_rec);
+
+      if (!REG_P (reg))
+	continue;
+
+      add_to_hard_reg_set (&hardregs, GET_MODE (reg),
+			   REGNO (reg));
+    }
+  if (hard_reg_set_intersect_p (hardregs, set_up_by_prologue))
+    return true;
+
   return false;
 }
 #endif
@@ -5455,7 +5457,7 @@  thread_prologue_and_epilogue_insns (void
   basic_block last_bb;
   bool last_bb_active ATTRIBUTE_UNUSED;
 #ifdef HAVE_simple_return
-  VEC (basic_block, heap) *unconverted_simple_returns = NULL;
+  VEC (rtx, heap) *unconverted_simple_returns = NULL;
   basic_block simple_return_block_hot = NULL;
   basic_block simple_return_block_cold = NULL;
   bool nonempty_prologue;
@@ -5575,6 +5577,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;
       rtx p_insn;
 
       VEC(basic_block, heap) *vec;
@@ -5610,6 +5613,16 @@  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);
+      if (frame_pointer_needed)
+	add_to_hard_reg_set (&set_up_by_prologue, Pmode,
+			     HARD_FRAME_POINTER_REGNUM);
+      if (pic_offset_table_rtx)
+	add_to_hard_reg_set (&set_up_by_prologue, Pmode,
+			     PIC_OFFSET_TABLE_REGNUM);
+
       FOR_EACH_BB (bb)
 	{
 	  rtx insn;
@@ -5628,7 +5641,8 @@  thread_prologue_and_epilogue_insns (void
 	    }
 	  else
 	    FOR_BB_INSNS (bb, insn)
-	      if (requires_stack_frame_p (insn, prologue_used))
+	      if (requires_stack_frame_p (insn, prologue_used,
+					  set_up_by_prologue))
 		{
 		  bitmap_set_bit (&bb_flags, bb->index);
 		  VEC_quick_push (basic_block, vec, bb);
@@ -5872,8 +5886,8 @@  thread_prologue_and_epilogue_insns (void
 		{
 #ifdef HAVE_simple_return
 		  if (simple_p)
-		    VEC_safe_push (basic_block, heap,
-				   unconverted_simple_returns, bb);
+		    VEC_safe_push (rtx, heap,
+				   unconverted_simple_returns, jump);
 #endif
 		  continue;
 		}
@@ -5891,8 +5905,8 @@  thread_prologue_and_epilogue_insns (void
 	    {
 #ifdef HAVE_simple_return
 	      if (simple_p)
-		VEC_safe_push (basic_block, heap,
-			       unconverted_simple_returns, bb);
+		VEC_safe_push (rtx, heap,
+			       unconverted_simple_returns, jump);
 #endif
 	      continue;
 	    }
@@ -6022,6 +6036,7 @@  epilogue_done:
       blocks = sbitmap_alloc (last_basic_block);
       sbitmap_zero (blocks);
       SET_BIT (blocks, entry_edge->dest->index);
+      SET_BIT (blocks, orig_entry_edge->dest->index);
       find_many_sub_basic_blocks (blocks);
       sbitmap_free (blocks);
 
@@ -6040,10 +6055,10 @@  epilogue_done:
      convert to conditional simple_returns, but couldn't for some
      reason, create a block to hold a simple_return insn and redirect
      those remaining edges.  */
-  if (!VEC_empty (basic_block, unconverted_simple_returns))
+  if (!VEC_empty (rtx, unconverted_simple_returns))
     {
       basic_block exit_pred = EXIT_BLOCK_PTR->prev_bb;
-      basic_block src_bb;
+      rtx jump;
       int i;
 
       gcc_assert (entry_edge != orig_entry_edge);
@@ -6061,8 +6076,9 @@  epilogue_done:
 	    simple_return_block_cold = e->dest;
 	}
 
-      FOR_EACH_VEC_ELT (basic_block, unconverted_simple_returns, i, src_bb)
+      FOR_EACH_VEC_ELT (rtx, unconverted_simple_returns, i, jump)
 	{
+	  basic_block src_bb = BLOCK_FOR_INSN (jump);
 	  edge e = find_edge (src_bb, last_bb);
 	  basic_block *pdest_bb;
 
@@ -6087,7 +6103,7 @@  epilogue_done:
 	    }
 	  redirect_edge_and_branch_force (e, *pdest_bb);
 	}
-      VEC_free (basic_block, heap, unconverted_simple_returns);
+      VEC_free (rtx, heap, unconverted_simple_returns);
     }
 #endif