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]

fix stdarg optimization for alpha


We'd been failing Jakub's stdarg optimization tests because we'd been
searching for the gpr counter field, didn't find it, and assumed that
meant the va_list had escaped.  Searching a bit harder lets us pass.

Also adds the bits to actually make use of this information and spill
fewer registers.


r~


        * config/alpha/alpha.c (va_list_skip_additions): Only define if
        TARGET_ABI_OSF.
        (TARGET_STDARG_OPTIMIZE_HOOK): Likewise.
        (alpha_stdarg_optimize_hook): Likewise.  Allow for one more round
        of indirection through ssa names while looking for the gpr counter
        field.
        (alpha_setup_incoming_varargs) <TARGET_ABI_OSF>: Make use of the
        saved va_list_gpr_size and va_list_fpr_size.

Index: config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.416
diff -u -p -d -r1.416 alpha.c
--- config/alpha/alpha.c	17 Apr 2005 06:19:17 -0000	1.416
+++ config/alpha/alpha.c	17 Apr 2005 19:22:11 -0000
@@ -5582,6 +5582,7 @@ alpha_build_builtin_va_list (void)
   return record;
 }
 
+#if TARGET_ABI_OSF
 /* Helper function for alpha_stdarg_optimize_hook.  Skip over casts
    and constant additions.  */
 
@@ -5685,17 +5686,16 @@ alpha_stdarg_optimize_hook (struct stdar
 
       arg1 = va_list_skip_additions (PHI_ARG_DEF (offset, 0));
       arg2 = va_list_skip_additions (PHI_ARG_DEF (offset, 1));
-      if (TREE_CODE (arg1) != COMPONENT_REF)
+      if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR)
 	{
 	  tree tem = arg1;
-
 	  arg1 = arg2;
 	  arg2 = tem;
-	}
 
-      if ((TREE_CODE (arg2) != MINUS_EXPR
-	   && TREE_CODE (arg2) != PLUS_EXPR)
-	  || !host_integerp (TREE_OPERAND (arg2, 1), 0))
+	  if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR)
+	    goto escapes;
+	}
+      if (!host_integerp (TREE_OPERAND (arg2, 1), 0))
 	goto escapes;
 
       sub = tree_low_cst (TREE_OPERAND (arg2, 1), 0);
@@ -5705,8 +5705,13 @@ alpha_stdarg_optimize_hook (struct stdar
 	goto escapes;
 
       arg2 = va_list_skip_additions (TREE_OPERAND (arg2, 0));
-      if (arg1 != arg2
-	  || TREE_CODE (arg1) != COMPONENT_REF
+      if (arg1 != arg2)
+	goto escapes;
+
+      if (TREE_CODE (arg1) == SSA_NAME)
+	arg1 = va_list_skip_additions (arg1);
+
+      if (TREE_CODE (arg1) != COMPONENT_REF
 	  || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
 	  || get_base_address (arg1) != base)
 	goto escapes;
@@ -5727,6 +5732,7 @@ escapes:
   si->va_list_escapes = true;
   return false;
 }
+#endif
 
 /* Perform any needed actions needed for a function that is receiving a
    variable number of arguments.  */
@@ -5787,21 +5793,38 @@ alpha_setup_incoming_varargs (CUMULATIVE
 
   if (!no_rtl)
     {
-      int set = get_varargs_alias_set ();
+      int count, set = get_varargs_alias_set ();
       rtx tmp;
 
-      tmp = gen_rtx_MEM (BLKmode,
-			 plus_constant (virtual_incoming_args_rtx,
-					(cum + 6) * UNITS_PER_WORD));
-      set_mem_alias_set (tmp, set);
-      move_block_from_reg (16 + cum, tmp, 6 - cum);
+      count = cfun->va_list_gpr_size / UNITS_PER_WORD;
+      if (count > 6 - cum)
+	count = 6 - cum;
 
-      tmp = gen_rtx_MEM (BLKmode,
-			 plus_constant (virtual_incoming_args_rtx,
-					cum * UNITS_PER_WORD));
-      set_mem_alias_set (tmp, set);
-      move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, 6 - cum);
-    }
+      /* Detect whether integer registers or floating-point registers
+	 are needed by the detected va_arg statements.  See above for
+	 how these values are computed.  Note that the "escape" value
+	 is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of 
+	 these bits set.  */
+      gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3);
+
+      if (cfun->va_list_fpr_size & 1)
+	{
+	  tmp = gen_rtx_MEM (BLKmode,
+			     plus_constant (virtual_incoming_args_rtx,
+					    (cum + 6) * UNITS_PER_WORD));
+	  set_mem_alias_set (tmp, set);
+	  move_block_from_reg (16 + cum, tmp, count);
+	}
+
+      if (cfun->va_list_fpr_size & 2)
+	{
+	  tmp = gen_rtx_MEM (BLKmode,
+			     plus_constant (virtual_incoming_args_rtx,
+					    cum * UNITS_PER_WORD));
+	  set_mem_alias_set (tmp, set);
+	  move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, count);
+	}
+     }
   *pretend_size = 12 * UNITS_PER_WORD;
 #endif
 }
@@ -10300,6 +10323,8 @@ alpha_init_libfuncs (void)
 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+#undef TARGET_STDARG_OPTIMIZE_HOOK
+#define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
 #endif
 
 #undef TARGET_RTX_COSTS
@@ -10353,9 +10378,6 @@ alpha_init_libfuncs (void)
 #undef TARGET_HANDLE_OPTION
 #define TARGET_HANDLE_OPTION alpha_handle_option
 
-#undef TARGET_STDARG_OPTIMIZE_HOOK
-#define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
-
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 


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