This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[stack]: PATCH: Optimize leaf function and check DRAP for PIC


Hi,

For leaf function, there is no outgoing stack.  We don't need to align stack
for outgoing stack boundary. Also, we can't use the same register for both
PIC and DRAP. This patch optimize stack alignment for leaf function and
avoid DRAP register when choosing PIC register. I will check it into stack
branch after regression tests on Linux/ia32 and Linux/Intel64.


H..J.
2008-03-24  H.J. Lu  <hongjiu.lu@intel.com>

	* cfgexpand.c (get_decl_align_unit): Update stack_alignment_used.
	* function.c (assign_stack_local_1): Likewise.
	(locate_and_pad_parm): Likewise.
	(allocate_struct_function): Initialize stack_alignment_used.

	* function.h (function): Update stack_alignment_needed
	comment.  Add stack_alignment_used.

	* config/i386/i386.c (ix86_expand_prologue): For leaf
	function, check stack_alignment_used stack_realign_really.

2008-03-24  Joey Ye  <joey.ye@intel.com>
	    H.J. Lu  <hongjiu.lu@intel.com>

	* config/i386/i386.c (ix86_select_alt_pic_regnum): Check
	DRAP register.

Index: gcc/function.c
===================================================================
--- gcc/function.c	(revision 1911)
+++ gcc/function.c	(working copy)
@@ -403,7 +403,7 @@ assign_stack_local_1 (enum machine_mode 
 {
   rtx x, addr;
   int bigend_correction = 0;
-  unsigned int alignment, mode_alignment;
+  unsigned int alignment, mode_alignment, alignment_in_bits;
   int frame_off, frame_alignment, frame_phase;
 
   if (mode == BLKmode)
@@ -435,16 +435,17 @@ assign_stack_local_1 (enum machine_mode 
   else
     alignment = align / BITS_PER_UNIT;
 
+  alignment_in_bits = alignment * BITS_PER_UNIT;
+
   if (FRAME_GROWS_DOWNWARD)
     function->x_frame_offset -= size;
 
   if (MAX_VECTORIZE_STACK_ALIGNMENT)
     {
-      if (function->stack_alignment_estimated < alignment * BITS_PER_UNIT)
+      if (function->stack_alignment_estimated < alignment_in_bits)
 	{
           if (!function->stack_realign_processed)
-            function->stack_alignment_estimated
-	      = alignment * BITS_PER_UNIT;
+            function->stack_alignment_estimated = alignment_in_bits;
           else
 	    {
 	      gcc_assert (!function->stack_realign_finalized);
@@ -458,6 +459,7 @@ assign_stack_local_1 (enum machine_mode 
 				  >= mode_alignment));
 		  alignment = (function->stack_alignment_estimated
 			       / BITS_PER_UNIT);
+		  alignment_in_bits = alignment * BITS_PER_UNIT;
 		}
 	    }
 	}
@@ -469,8 +471,10 @@ assign_stack_local_1 (enum machine_mode 
       if (alignment * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
 	alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
     }
-  if (function->stack_alignment_needed < alignment * BITS_PER_UNIT)
-    function->stack_alignment_needed = alignment * BITS_PER_UNIT;
+  if (function->stack_alignment_needed < alignment_in_bits)
+    function->stack_alignment_needed = alignment_in_bits;
+  if (function->stack_alignment_used < function->stack_alignment_needed)
+    function->stack_alignment_used = function->stack_alignment_needed;
 
   /* Calculate how many bytes the start of local variables is off from
      stack alignment.  */
@@ -3452,6 +3456,8 @@ locate_and_pad_parm (enum machine_mode p
     }
   if (cfun->stack_alignment_needed < boundary)
     cfun->stack_alignment_needed = boundary;
+  if (cfun->stack_alignment_used < cfun->stack_alignment_needed)
+    cfun->stack_alignment_used = cfun->stack_alignment_needed;
 
 #ifdef ARGS_GROW_DOWNWARD
   locate->slot_offset.constant = -initial_offset_ptr->constant;
@@ -4007,6 +4013,7 @@ allocate_struct_function (tree fndecl, b
   cfun = ggc_alloc_cleared (sizeof (struct function));
 
   cfun->stack_alignment_needed = STACK_BOUNDARY;
+  cfun->stack_alignment_used = STACK_BOUNDARY;
   cfun->stack_alignment_estimated = STACK_BOUNDARY;
   cfun->preferred_stack_boundary = STACK_BOUNDARY;
 
Index: gcc/function.h
===================================================================
--- gcc/function.h	(revision 1911)
+++ gcc/function.h	(working copy)
@@ -295,9 +295,13 @@ struct function GTY(())
   /* tm.h can use this to store whatever it likes.  */
   struct machine_function * GTY ((maybe_undef)) machine;
 
-  /* The largest alignment of slot allocated on the stack.  */
+  /* The largest alignment needed on the stack, including requirement
+     for outgoing stack alignment.  */
   unsigned int stack_alignment_needed;
 
+  /* The largest alignment of slot allocated on the stack.  */
+  unsigned int stack_alignment_used;
+
   /* The estimated stack alignment.  */
   unsigned int stack_alignment_estimated;
 
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c	(revision 1911)
+++ gcc/cfgexpand.c	(working copy)
@@ -180,6 +180,8 @@ get_decl_align_unit (tree decl)
      So here we only make sure stack_alignment_needed >= align.  */
   if (cfun->stack_alignment_needed < align)
     cfun->stack_alignment_needed = align;
+  if (cfun->stack_alignment_used < cfun->stack_alignment_needed)
+    cfun->stack_alignment_used = cfun->stack_alignment_needed;
 
   return align / BITS_PER_UNIT;
 }
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 1911)
+++ gcc/config/i386/i386.c	(working copy)
@@ -5950,8 +5950,10 @@ ix86_select_alt_pic_regnum (void)
       && !ix86_current_function_calls_tls_descriptor)
     {
       int i;
+      /* Can't use the same register for both PIC and DRAP.  */
+      int drap = cfun->drap_reg ? REGNO (cfun->drap_reg) : - 1;
       for (i = 2; i >= 0; --i)
-        if (!df_regs_ever_live_p (i))
+        if (i != drap && !df_regs_ever_live_p (i))
 	  return i;
     }
 
@@ -6435,8 +6437,10 @@ ix86_expand_prologue (void)
 
   /* Check if stack realign is really needed after reload, and 
      stores result in cfun */
-  cfun->stack_realign_really = ix86_incoming_stack_boundary 
-                               < cfun->stack_alignment_needed;
+  cfun->stack_realign_really = (ix86_incoming_stack_boundary
+				< (current_function_is_leaf
+				   ? cfun->stack_alignment_used
+				   : cfun->stack_alignment_needed));
 
   cfun->stack_realign_finalized = true;
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]