Commit 0976078c by Richard Henderson Committed by Richard Henderson

function.c (pass_by_reference): New.

        * 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
parent fe984136
2004-07-13 Richard Henderson <rth@redhat.com> 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-def.h (TARGET_MUST_PASS_IN_STACK): New.
* target.h (struct gcc_target): Add calls.must_pass_in_stack. * target.h (struct gcc_target): Add calls.must_pass_in_stack.
* expr.h (MUST_PASS_IN_STACK): Remove. * expr.h (MUST_PASS_IN_STACK): Remove.
......
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> 2004-07-11 Joseph S. Myers <jsm@polyomino.org.uk>
* misc.c (LANG_HOOKS_CLEAR_BINDING_STACK, LANG_HOOKS_PUSHLEVEL, * misc.c (LANG_HOOKS_CLEAR_BINDING_STACK, LANG_HOOKS_PUSHLEVEL,
......
...@@ -697,26 +697,26 @@ gnat_get_alias_set (tree type) ...@@ -697,26 +697,26 @@ gnat_get_alias_set (tree type)
int int
default_pass_by_ref (tree gnu_type) 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 /* We pass aggregates by reference if they are sufficiently large. The
choice of constant here is somewhat arbitrary. We also pass by choice of constant here is somewhat arbitrary. We also pass by
reference if the target machine would either pass or return by reference if the target machine would either pass or return by
reference. Strictly speaking, we need only check the return if this 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 is an In Out parameter, but it's probably best to err on the side of
passing more things by reference. */ passing more things by reference. */
return (0
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE if (pass_by_reference (NULL, TYPE_MODE (gnu_type), gnu_type, 1))
|| FUNCTION_ARG_PASS_BY_REFERENCE (cum, TYPE_MODE (gnu_type), return true;
gnu_type, 1)
#endif if (targetm.calls.return_in_memory (gnu_type, NULL_TREE))
|| targetm.calls.return_in_memory (gnu_type, NULL_TREE) return true;
|| (AGGREGATE_TYPE_P (gnu_type)
&& (! host_integerp (TYPE_SIZE (gnu_type), 1) if (AGGREGATE_TYPE_P (gnu_type)
|| 0 < compare_tree_int (TYPE_SIZE (gnu_type), && (! host_integerp (TYPE_SIZE (gnu_type), 1)
8 * TYPE_ALIGN (gnu_type))))); || 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 /* GNU_TYPE is the type of a subprogram parameter. Determine from the type if
......
...@@ -974,11 +974,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, ...@@ -974,11 +974,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
with those made by function.c. */ with those made by function.c. */
/* See if this argument should be passed by invisible reference. */ /* See if this argument should be passed by invisible reference. */
if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type)) if (pass_by_reference (args_so_far, TYPE_MODE (type),
|| TREE_ADDRESSABLE (type) type, argpos < n_named_args))
|| FUNCTION_ARG_PASS_BY_REFERENCE (*args_so_far, TYPE_MODE (type),
type, argpos < n_named_args)
)
{ {
/* If we're compiling a thunk, pass through invisible /* If we're compiling a thunk, pass through invisible
references instead of making a copy. */ references instead of making a copy. */
...@@ -3559,7 +3556,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, ...@@ -3559,7 +3556,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
&& ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val))) && ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val)))
val = force_operand (val, NULL_RTX); 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; rtx slot;
int must_copy = ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode, int must_copy = ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode,
......
...@@ -207,10 +207,6 @@ do { \ ...@@ -207,10 +207,6 @@ do { \
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
#endif #endif
#ifndef FUNCTION_ARG_PASS_BY_REFERENCE
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
#endif
#ifndef FUNCTION_ARG_CALLEE_COPIES #ifndef FUNCTION_ARG_CALLEE_COPIES
#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0 #define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0
#endif #endif
......
...@@ -2026,6 +2026,33 @@ use_register_for_decl (tree decl) ...@@ -2026,6 +2026,33 @@ use_register_for_decl (tree decl)
return (optimize || DECL_REGISTER (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. /* Structures to communicate between the subroutines of assign_parms.
The first holds data persistent across all parameters, the second The first holds data persistent across all parameters, the second
is cleared out for each parameter. */ is cleared out for each parameter. */
...@@ -2236,14 +2263,9 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, ...@@ -2236,14 +2263,9 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
&& TYPE_TRANSPARENT_UNION (passed_type))) && TYPE_TRANSPARENT_UNION (passed_type)))
passed_type = TREE_TYPE (TYPE_FIELDS (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 /* See if this arg was passed by invisible reference. */
object whose size depends on the contents of the object itself or if if (pass_by_reference (&all->args_so_far, passed_mode,
the machine requires these objects be passed that way. */ passed_type, data->named_arg))
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)
)
{ {
passed_type = nominal_type = build_pointer_type (passed_type); passed_type = nominal_type = build_pointer_type (passed_type);
data->passed_pointer = true; data->passed_pointer = true;
......
...@@ -556,4 +556,7 @@ extern void init_function_once (void); ...@@ -556,4 +556,7 @@ extern void init_function_once (void);
extern void do_warn_unused_parameter (tree); extern void do_warn_unused_parameter (tree);
extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
#endif /* GCC_FUNCTION_H */ #endif /* GCC_FUNCTION_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment