summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-13 08:22:03 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-13 08:22:03 +0000
commitcc9b8628228057b9b0ab5417b7d8deea36754e44 (patch)
tree9ce1ffbe5f574651dfe2baa17807ad50e4394b8d
parent0336f0f0a448f834556a8efb0cf4161c2e2a38d2 (diff)
downloadgcc-cc9b8628228057b9b0ab5417b7d8deea36754e44.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84607 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/ada/misc.c28
-rw-r--r--gcc/calls.c9
-rw-r--r--gcc/expr.h4
-rw-r--r--gcc/function.c38
-rw-r--r--gcc/function.h3
7 files changed, 63 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6c2ef13d44b..2a73f888851 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
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.
* target.h (struct gcc_target): Add calls.must_pass_in_stack.
* expr.h (MUST_PASS_IN_STACK): Remove.
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 55fc42ae58f..452ed38e6ff 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -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,
diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c
index 9d0e31e1ee1..37e6f17d1be 100644
--- a/gcc/ada/misc.c
+++ b/gcc/ada/misc.c
@@ -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
diff --git a/gcc/calls.c b/gcc/calls.c
index e1281624a05..88bac101ae8 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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,
diff --git a/gcc/expr.h b/gcc/expr.h
index 687b6e3943f..9a50410131e 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -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
diff --git a/gcc/function.c b/gcc/function.c
index 19698f99214..08b2e439bbc 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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;
diff --git a/gcc/function.h b/gcc/function.h
index a90a5009325..5ac7731daca 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -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 */