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
This commit is contained in:
parent
fe9841365e
commit
0976078c73
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue