OSDN Git Service

* config/alpha/alpha.c (va_list_skip_additions): Only define if
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 17 Apr 2005 19:29:01 +0000 (19:29 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 17 Apr 2005 19:29:01 +0000 (19:29 +0000)
        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.

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

gcc/ChangeLog
gcc/config/alpha/alpha.c

index 97a1c53..4b409de 100644 (file)
@@ -1,3 +1,14 @@
+2005-04-17  Richard Henderson  <rth@redhat.com>
+
+       * 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.
+
 2005-04-17  Kazu Hirata  <kazu@cs.umass.edu>
 
        * tree-vrp.c (compare_values): Check that VAL1 and VAL2 are
index fdcbf1b..71ba449 100644 (file)
@@ -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 stdarg_info *si, tree lhs, tree rhs)
 
       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 stdarg_info *si, tree lhs, tree rhs)
        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_ARGS *pcum, enum machine_mode mode,
 
   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;
 
 \f