https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770

--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Completely untested WIP patch:
--- gcc/config/i386/i386.c.jj   2020-04-27 13:50:39.529692389 +0200
+++ gcc/config/i386/i386.c      2020-04-27 14:03:12.479322957 +0200
@@ -16550,6 +16550,23 @@ ix86_is_empty_record (const_tree type)
   return default_is_empty_record (type);
 }

+/* Implement TARGET_EMPTY_TYPE_P.  */
+
+static bool
+ix86_empty_type_p (const_tree fntype, const_tree type)
+{
+  if (!TYPE_EMPTY_P (type))
+    return false;
+  if (fntype)
+    {
+      if (ix86_function_type_abi (fntype) == MS_ABI)
+       return false;
+    }
+  else if (ix86_cfun_abi () == MS_ABI)
+    return false;
+  return true;
+}
+
 /* Implement TARGET_WARN_PARAMETER_PASSING_ABI.  */

 static void
@@ -23470,6 +23487,8 @@ ix86_run_selftests (void)

 #undef TARGET_EMPTY_RECORD_P
 #define TARGET_EMPTY_RECORD_P ix86_is_empty_record
+#undef TARGET_EMPTY_TYPE_P
+#define TARGET_EMPTY_TYPE_P ix86_empty_type_p

 #undef TARGET_WARN_PARAMETER_PASSING_ABI
 #define TARGET_WARN_PARAMETER_PASSING_ABI ix86_warn_parameter_passing_abi
--- gcc/function.c.jj   2020-04-16 10:15:06.841126753 +0200
+++ gcc/function.c      2020-04-27 14:21:27.669799119 +0200
@@ -2102,7 +2102,7 @@ aggregate_value_p (const_tree exp, const
   if (TREE_ADDRESSABLE (type))
     return 1;

-  if (TYPE_EMPTY_P (type))
+  if (targetm.calls.empty_type_p (fntype, type))
     return 0;

   if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type))
@@ -3095,7 +3095,8 @@ assign_parm_setup_block (struct assign_p
        move_block_from_reg (REGNO (entry_parm), mem,
                             size_stored / UNITS_PER_WORD);
     }
-  else if (data->stack_parm == 0 && !TYPE_EMPTY_P (data->arg.type))
+  else if (data->stack_parm == 0
+          && !targetm.calls.empty_type_p (NULL_TREE, data->arg.type))
     {
       push_to_sequence2 (all->first_conversion_insn,
all->last_conversion_insn);
       emit_block_move (stack_parm, data->entry_parm, GEN_INT (size),
@@ -3496,7 +3497,7 @@ assign_parm_setup_stack (struct assign_p
       dest = validize_mem (copy_rtx (data->stack_parm));
       src = validize_mem (copy_rtx (data->entry_parm));

-      if (TYPE_EMPTY_P (data->arg.type))
+      if (targetm.calls.empty_type_p (NULL_TREE, data->arg.type))
        /* Empty types don't really need to be copied.  */;
       else if (MEM_P (src))
        {
@@ -3657,7 +3658,7 @@ assign_parms (tree fndecl)
             passing area, have non-zero size and have address taken,
             force creation of a stack slot so that they have distinct
             address from other parameters.  */
-         if (TYPE_EMPTY_P (data.arg.type)
+         if (targetm.calls.empty_type_p (NULL_TREE, data.arg.type)
              && TREE_ADDRESSABLE (parm)
              && data.entry_parm == data.stack_parm
              && MEM_P (data.entry_parm)
--- gcc/targhooks.h.jj  2020-01-12 11:54:36.939405473 +0100
+++ gcc/targhooks.h     2020-04-27 13:57:13.113741631 +0200
@@ -246,6 +246,7 @@ extern unsigned int default_dwarf_poly_i
                                                            int *);
 extern machine_mode default_dwarf_frame_reg_mode (int);
 extern fixed_size_mode default_get_reg_raw_mode (int);
+extern bool default_empty_type_p (const_tree, const_tree);
 extern bool default_keep_leaf_when_profiled ();

 extern void *default_get_pch_validity (size_t *);
--- gcc/targhooks.c.jj  2020-01-21 09:14:07.566267369 +0100
+++ gcc/targhooks.c     2020-04-27 14:07:27.228481737 +0200
@@ -1945,6 +1945,12 @@ default_get_reg_raw_mode (int regno)
   return as_a <fixed_size_mode> (reg_raw_mode[regno]);
 }

+bool
+default_empty_type_p (const_tree, const_tree type)
+{
+  return TYPE_EMPTY_P (type);
+}
+
 /* Return true if a leaf function should stay leaf even with profiling
    enabled.  */

@@ -2190,7 +2196,7 @@ std_gimplify_va_arg_expr (tree valist, t
   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
      requires greater alignment, we must perform dynamic alignment.  */
   if (boundary > align
-      && !TYPE_EMPTY_P (type)
+      && !targetm.calls.empty_type_p (NULL_TREE, type)
       && !integer_zerop (TYPE_SIZE (type)))
     {
       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
--- gcc/calls.c.jj      2020-04-27 09:10:50.593968911 +0200
+++ gcc/calls.c 2020-04-27 14:12:14.046156465 +0200
@@ -146,12 +146,13 @@ static unsigned HOST_WIDE_INT stored_arg
 static int stack_arg_under_construction;

 static void precompute_register_parameters (int, struct arg_data *, int *);
-static int store_one_arg (struct arg_data *, rtx, int, int, int);
+static int store_one_arg (const_tree, struct arg_data *, rtx, int, int, int);
 static void store_unaligned_arguments_into_pseudos (struct arg_data *, int);
 static int finalize_must_preallocate (int, int, struct arg_data *,
                                      struct args_size *);
 static void precompute_arguments (int, struct arg_data *);
-static void compute_argument_addresses (struct arg_data *, rtx, int);
+static void compute_argument_addresses (const_tree, struct arg_data *, rtx,
+                                       int);
 static rtx rtx_for_function_call (tree, tree);
 static void load_register_parameters (struct arg_data *, int, rtx *, int,
                                      int, int *);
@@ -2769,7 +2770,8 @@ finalize_must_preallocate (int must_prea
    ARGBLOCK is an rtx for the address of the outgoing arguments.  */

 static void
-compute_argument_addresses (struct arg_data *args, rtx argblock, int
num_actuals)
+compute_argument_addresses (const_tree funtype, struct arg_data *args,
+                           rtx argblock, int num_actuals)
 {
   if (argblock)
     {
@@ -2798,7 +2800,8 @@ compute_argument_addresses (struct arg_d
              && args[i].partial == 0)
            continue;

-         if (TYPE_EMPTY_P (TREE_TYPE (args[i].tree_value)))
+         if (targetm.calls.empty_type_p (funtype,
+                                         TREE_TYPE (args[i].tree_value)))
            continue;

          addr = simplify_gen_binary (PLUS, Pmode, arg_reg, offset);
@@ -4384,7 +4387,7 @@ expand_call (tree exp, rtx target, int i
              }
        }

-      compute_argument_addresses (args, argblock, num_actuals);
+      compute_argument_addresses (funtype, args, argblock, num_actuals);

       /* Stack is properly aligned, pops can't safely be deferred during
         the evaluation of the arguments.  */
@@ -4473,7 +4476,7 @@ expand_call (tree exp, rtx target, int i
                  continue;
                }

-             if (store_one_arg (&args[i], argblock, flags,
+             if (store_one_arg (funtype, &args[i], argblock, flags,
                                 adjusted_args_size.var != 0,
                                 reg_parm_stack_space)
                  || (pass == 0
@@ -4513,7 +4516,7 @@ expand_call (tree exp, rtx target, int i
                  break;
                }

-             if (store_one_arg (&args[i], argblock, flags,
+             if (store_one_arg (funtype, &args[i], argblock, flags,
                                 adjusted_args_size.var != 0,
                                 reg_parm_stack_space)
                  || (pass == 0
@@ -5845,8 +5848,9 @@ emit_library_call_value_1 (int retval, r
    zero otherwise.  */

 static int
-store_one_arg (struct arg_data *arg, rtx argblock, int flags,
-              int variable_size ATTRIBUTE_UNUSED, int reg_parm_stack_space)
+store_one_arg (const_tree funtype, struct arg_data *arg, rtx argblock,
+              int flags, int variable_size ATTRIBUTE_UNUSED,
+              int reg_parm_stack_space)
 {
   tree pval = arg->tree_value;
   rtx reg = 0;
@@ -6016,7 +6020,7 @@ store_one_arg (struct arg_data *arg, rtx
         Note that in C the default argument promotions
         will prevent such mismatches.  */

-      poly_int64 size = (TYPE_EMPTY_P (TREE_TYPE (pval))
+      poly_int64 size = (targetm.calls.empty_type_p (funtype, TREE_TYPE
(pval))
                         ? 0 : GET_MODE_SIZE (arg->mode));

       /* Compute how much space the push instruction will push.
--- gcc/doc/tm.texi.jj  2020-03-17 13:50:52.844934839 +0100
+++ gcc/doc/tm.texi     2020-04-27 14:17:07.848721305 +0200
@@ -4693,6 +4693,12 @@ This target hook returns true if the typ
 is to return @code{false}.
 @end deftypefn

+@deftypefn {Target Hook} bool TARGET_EMPTY_TYPE_P (const_tree @var{fndecl},
const_tree @var{type})
+This target hook returns true if the type is an empty record in the ABI
+of function type @var{fntype}, or if NULL of the current function.  The
+default is to return @code{TYPE_EMPTY_P(@var{type})}.
+@end deftypefn
+
 @deftypefn {Target Hook} void TARGET_WARN_PARAMETER_PASSING_ABI
(cumulative_args_t @var{ca}, tree @var{type})
 This target hook warns about the change in empty class parameter passing
 ABI.
--- gcc/doc/tm.texi.in.jj       2020-03-12 09:35:05.432126619 +0100
+++ gcc/doc/tm.texi.in  2020-04-27 14:17:02.920795688 +0200
@@ -3490,6 +3490,8 @@ nothing when you use @option{-freg-struc

 @hook TARGET_EMPTY_RECORD_P

+@hook TARGET_EMPTY_TYPE_P
+
 @hook TARGET_WARN_PARAMETER_PASSING_ABI

 @node Caller Saves
--- gcc/target.def.jj   2020-03-17 13:50:52.713936762 +0100
+++ gcc/target.def      2020-04-27 14:16:25.740356959 +0200
@@ -5225,6 +5225,15 @@ is to return @code{false}.",
  bool, (const_tree type),
  hook_bool_const_tree_false)

+/* Return true if a type is an empty record in a particular ABI context.  */
+DEFHOOK
+(empty_type_p,
+ "This target hook returns true if the type is an empty record in the ABI\n\
+of function type @var{fntype}, or if NULL of the current function.  The\n\
+default is to return @code{TYPE_EMPTY_P(@var{type})}.",
+ bool, (const_tree fndecl, const_tree type),
+ default_empty_type_p)
+
 /* Warn about the change in empty class parameter passing ABI.  */
 DEFHOOK
 (warn_parameter_passing_abi,

The remaining problem are (besides testing) that two last uses of TYPE_EMPTY_P
in tree.c and one use in calls.c need to pass in information on the function
type being called if it is on the caller side, or NULL on the callee side, and
that means the function needs new argument, and associated target hook too etc.
:(

Reply via email to