function.c (pass_by_reference): New.
authorRichard Henderson <rth@redhat.com>
Tue, 13 Jul 2004 08:22:03 +0000 (01:22 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 13 Jul 2004 08:22:03 +0000 (01:22 -0700)
        * function.c (pass_by_reference): New.
        (assign_parm_find_data_types): Use it.
        * calls.c (initialize_argument_information): Likewise.
        (emit_library_call_value_1): Likewise.
        * expr.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove.
        * function.h (pass_by_reference): Declare.
ada/
        * misc.c (default_pass_by_ref): Use pass_by_reference.

From-SVN: r84607

gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/misc.c
gcc/calls.c
gcc/expr.h
gcc/function.c
gcc/function.h

index 6c2ef13d44b18cfde53886578868615385f147e0..2a73f888851e819cd2f1d15a8efab891cc8993c5 100644 (file)
@@ -1,3 +1,12 @@
+2004-07-13  Richard Henderson  <rth@redhat.com>
+
+       * function.c (pass_by_reference): New.
+       (assign_parm_find_data_types): Use it.
+       * calls.c (initialize_argument_information): Likewise.
+       (emit_library_call_value_1): Likewise.
+       * expr.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove.
+       * function.h (pass_by_reference): Declare.
+
 2004-07-13  Richard Henderson  <rth@redhat.com>
 
        * target-def.h (TARGET_MUST_PASS_IN_STACK): New.
index 55fc42ae58fc6238c3ef174d1b3252f889dd75b6..452ed38e6ffda9f7b0bccdcf44fb03ccfc36fe37 100644 (file)
@@ -1,3 +1,7 @@
+2004-07-13  Richard Henderson  <rth@redhat.com>
+
+       * misc.c (default_pass_by_ref): Use pass_by_reference.
+
 2004-07-11  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        * misc.c (LANG_HOOKS_CLEAR_BINDING_STACK, LANG_HOOKS_PUSHLEVEL,
index 9d0e31e1ee1b96854fbd05399ea84b1f32c85da8..37e6f17d1be65384e4ad85713b637b12d5ef7c8d 100644 (file)
@@ -697,26 +697,26 @@ gnat_get_alias_set (tree type)
 int
 default_pass_by_ref (tree gnu_type)
 {
-  CUMULATIVE_ARGS cum;
-
-  INIT_CUMULATIVE_ARGS (cum, NULL_TREE, NULL_RTX, 0, 2);
-
   /* We pass aggregates by reference if they are sufficiently large.  The
      choice of constant here is somewhat arbitrary.  We also pass by
      reference if the target machine would either pass or return by
      reference.  Strictly speaking, we need only check the return if this
      is an In Out parameter, but it's probably best to err on the side of
      passing more things by reference.  */
-  return (0
-#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
-         || FUNCTION_ARG_PASS_BY_REFERENCE (cum, TYPE_MODE (gnu_type),
-                                            gnu_type, 1)
-#endif
-         || targetm.calls.return_in_memory (gnu_type, NULL_TREE)
-         || (AGGREGATE_TYPE_P (gnu_type)
-             && (! host_integerp (TYPE_SIZE (gnu_type), 1)
-                 || 0 < compare_tree_int (TYPE_SIZE (gnu_type),
-                                          8 * TYPE_ALIGN (gnu_type)))));
+
+  if (pass_by_reference (NULL, TYPE_MODE (gnu_type), gnu_type, 1))
+    return true;
+
+  if (targetm.calls.return_in_memory (gnu_type, NULL_TREE))
+    return true;
+  
+  if (AGGREGATE_TYPE_P (gnu_type)
+      && (! host_integerp (TYPE_SIZE (gnu_type), 1)
+         || 0 < compare_tree_int (TYPE_SIZE (gnu_type),
+                                  8 * TYPE_ALIGN (gnu_type))))
+    return true;
+
+  return false;
 }
 
 /* GNU_TYPE is the type of a subprogram parameter.  Determine from the type if
index e1281624a05e70df1505abf8007e0005341fcfde..88bac101ae8e4e9e77acfb504f2e65308c511292 100644 (file)
@@ -974,11 +974,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
         with those made by function.c.  */
 
       /* See if this argument should be passed by invisible reference.  */
-      if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
-         || TREE_ADDRESSABLE (type)
-         || FUNCTION_ARG_PASS_BY_REFERENCE (*args_so_far, TYPE_MODE (type),
-                                            type, argpos < n_named_args)
-         )
+      if (pass_by_reference (args_so_far, TYPE_MODE (type),
+                            type, argpos < n_named_args))
        {
          /* If we're compiling a thunk, pass through invisible
              references instead of making a copy.  */
@@ -3559,7 +3556,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
          && ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val)))
        val = force_operand (val, NULL_RTX);
 
-      if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1))
+      if (pass_by_reference (&args_so_far, mode, NULL_TREE, 1))
        {
          rtx slot;
          int must_copy = ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode,
index 687b6e3943f47fe0e68ffa9511753e7ebf426386..9a50410131ee97bcb3d8d8b9f577bbed118916fc 100644 (file)
@@ -207,10 +207,6 @@ do {                                                       \
 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
 #endif
 
-#ifndef FUNCTION_ARG_PASS_BY_REFERENCE
-#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
-#endif
-
 #ifndef FUNCTION_ARG_CALLEE_COPIES
 #define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0
 #endif
index 19698f99214bea47d27da61811b3eb2694f2d109..08b2e439bbce58a5bced777d261f36e00470ee71 100644 (file)
@@ -2026,6 +2026,33 @@ use_register_for_decl (tree decl)
   return (optimize || DECL_REGISTER (decl));
 }
 
+/* Return true if TYPE should be passed by invisible reference.  */
+
+bool
+pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+                  enum machine_mode mode ATTRIBUTE_UNUSED,
+                  tree type, bool named_arg ATTRIBUTE_UNUSED)
+{
+  if (type)
+    {
+      /* If this type contains non-trivial constructors, then it is
+        forbidden for the middle-end to create any new copies.  */
+      if (TREE_ADDRESSABLE (type))
+       return true;
+
+      /* If an object's size is dependent on itself, there's no way
+        to *not* pass by reference.  */
+      if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type)))
+       return true;
+    }
+
+#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
+  return FUNCTION_ARG_PASS_BY_REFERENCE (*ca, mode, type, named_arg);
+#else
+  return false;
+#endif
+}
+
 /* Structures to communicate between the subroutines of assign_parms.
    The first holds data persistent across all parameters, the second
    is cleared out for each parameter.  */
@@ -2236,14 +2263,9 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
          && TYPE_TRANSPARENT_UNION (passed_type)))
     passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
 
-  /* See if this arg was passed by invisible reference.  It is if it is an
-     object whose size depends on the contents of the object itself or if
-     the machine requires these objects be passed that way.  */
-  if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (passed_type))
-      || TREE_ADDRESSABLE (passed_type)
-      || FUNCTION_ARG_PASS_BY_REFERENCE (all->args_so_far, passed_mode,
-                                        passed_type, data->named_arg)
-      )
+  /* See if this arg was passed by invisible reference.  */
+  if (pass_by_reference (&all->args_so_far, passed_mode,
+                        passed_type, data->named_arg))
     {
       passed_type = nominal_type = build_pointer_type (passed_type);
       data->passed_pointer = true;
index a90a5009325bc3067dfc22e0c5922b62f10f5ac9..5ac7731dacaadb08606c631ef27512ad082d6d8d 100644 (file)
@@ -556,4 +556,7 @@ extern void init_function_once (void);
 
 extern void do_warn_unused_parameter (tree);
 
+extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
+                              tree, bool);
+
 #endif  /* GCC_FUNCTION_H */