OSDN Git Service

* function.h (requires_stack_frame_p): New prototype.
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Nov 2011 21:28:57 +0000 (21:28 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Nov 2011 21:28:57 +0000 (21:28 +0000)
* function.c (requires_stack_frame_p): No longer static.
* config/i386/i386.c (ix86_finalize_stack_realign_flags): If
stack_realign_fp was just a conservative guess for a function
which doesn't use sp/fp/argp at all, clear frame_pointer_needed
and stack realignment.

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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/function.c
gcc/function.h

index ce1bac4..104de01 100644 (file)
@@ -1,3 +1,12 @@
+2011-11-09  Jakub Jelinek  <jakub@redhat.com>
+
+       * function.h (requires_stack_frame_p): New prototype.
+       * function.c (requires_stack_frame_p): No longer static.
+       * config/i386/i386.c (ix86_finalize_stack_realign_flags): If
+       stack_realign_fp was just a conservative guess for a function
+       which doesn't use sp/fp/argp at all, clear frame_pointer_needed
+       and stack realignment.
+
 2011-11-09  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR preprocessor/51061
index acf9ad8..008af27 100644 (file)
@@ -9928,12 +9928,68 @@ ix86_finalize_stack_realign_flags (void)
       /* After stack_realign_needed is finalized, we can't no longer
         change it.  */
       gcc_assert (crtl->stack_realign_needed == stack_realign);
+      return;
     }
-  else
-    {
-      crtl->stack_realign_needed = stack_realign;
-      crtl->stack_realign_finalized = true;
+
+  /* If the only reason for frame_pointer_needed is that we conservatively
+     assumed stack realignment might be needed, but in the end nothing that
+     needed the stack alignment had been spilled, clear frame_pointer_needed
+     and say we don't need stack realignment.  */
+  if (stack_realign
+      && !crtl->need_drap
+      && frame_pointer_needed
+      && current_function_is_leaf
+      && flag_omit_frame_pointer
+      && current_function_sp_is_unchanging
+      && !ix86_current_function_calls_tls_descriptor
+      && !crtl->accesses_prior_frames
+      && !cfun->calls_alloca
+      && !crtl->calls_eh_return
+      && !(flag_stack_check && STACK_CHECK_MOVING_SP)
+      && !ix86_frame_pointer_required ()
+      && get_frame_size () == 0
+      && ix86_nsaved_sseregs () == 0
+      && ix86_varargs_gpr_size + ix86_varargs_fpr_size == 0)
+    {
+      HARD_REG_SET set_up_by_prologue, prologue_used;
+      basic_block bb;
+
+      CLEAR_HARD_REG_SET (prologue_used);
+      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);
+      add_to_hard_reg_set (&set_up_by_prologue, Pmode,
+                          HARD_FRAME_POINTER_REGNUM);
+      FOR_EACH_BB (bb)
+        {
+          rtx insn;
+         FOR_BB_INSNS (bb, insn)
+           if (NONDEBUG_INSN_P (insn)
+               && requires_stack_frame_p (insn, prologue_used,
+                                          set_up_by_prologue))
+             {
+               crtl->stack_realign_needed = stack_realign;
+               crtl->stack_realign_finalized = true;
+               return;
+             }
+       }
+
+      frame_pointer_needed = false;
+      stack_realign = false;
+      crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
+      crtl->stack_alignment_needed = incoming_stack_boundary;
+      crtl->stack_alignment_estimated = incoming_stack_boundary;
+      if (crtl->preferred_stack_boundary > incoming_stack_boundary)
+       crtl->preferred_stack_boundary = incoming_stack_boundary;
+      df_finish_pass (true);
+      df_scan_alloc (NULL);
+      df_scan_blocks ();
+      df_compute_regs_ever_live (true);
+      df_analyze ();
     }
+
+  crtl->stack_realign_needed = stack_realign;
+  crtl->stack_realign_finalized = true;
 }
 
 /* Expand the prologue into a bunch of separate insns.  */
index 0cbbbc5..0ee69ef 100644 (file)
@@ -5284,7 +5284,7 @@ prologue_epilogue_contains (const_rtx insn)
    PROLOGUE_USED contains the hard registers used in the function
    prologue.  SET_UP_BY_PROLOGUE is the set of registers we expect the
    prologue to set up for the function.  */
-static bool
+bool
 requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used,
                        HARD_REG_SET set_up_by_prologue)
 {
index 42e52ac..ce67add 100644 (file)
@@ -753,6 +753,10 @@ extern void used_types_insert (tree);
 extern int get_next_funcdef_no (void);
 extern int get_last_funcdef_no (void);
 
+#ifdef HAVE_simple_return
+extern bool requires_stack_frame_p (rtx, HARD_REG_SET, HARD_REG_SET);
+#endif                        
+
 /* In predict.c */
 extern bool optimize_function_for_size_p (struct function *);
 extern bool optimize_function_for_speed_p (struct function *);