OSDN Git Service

* function.c (frame_required_for_rtx): Remove function.
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 7 Oct 2011 12:20:17 +0000 (12:20 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 7 Oct 2011 12:20:17 +0000 (12:20 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179654 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/function.c

index 9d0991e..c572234 100644 (file)
@@ -1,3 +1,14 @@
+2011-10-07  Bernd Schmidt  <bernds@codesourcery.com>
+
+       * 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.
+
 2011-10-07  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/50650
index ff63b94..85a0bb7 100644 (file)
@@ -5303,25 +5303,15 @@ record_hard_reg_uses (rtx *px, void *data)
   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_REG_SET prologue_used)
     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_REG_SET prologue_used)
     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