aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Evans <dje@gnu.org>1993-04-19 19:24:23 +0000
committerDoug Evans <dje@gnu.org>1993-04-19 19:24:23 +0000
commit5e0de251204954b4a332a2ed7417623ed826de3e (patch)
treecfbd4116ad8dc8f6ccdd649076ec02873f0c1902
parentfd6b2a6d3e5054e023b85c67e88910a4406d0935 (diff)
downloadgcc-5e0de251204954b4a332a2ed7417623ed826de3e.zip
gcc-5e0de251204954b4a332a2ed7417623ed826de3e.tar.gz
gcc-5e0de251204954b4a332a2ed7417623ed826de3e.tar.bz2
(expand_call): Use new FUNCTION_ARG_CALLEE_COPIES macro.
From-SVN: r4183
-rw-r--r--gcc/calls.c75
1 files changed, 47 insertions, 28 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 9ad7d16..f1cbfc2 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -915,41 +915,60 @@ expand_call (exp, target, ignore)
if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, TYPE_MODE (type), type,
argpos < n_named_args))
{
- /* We make a copy of the object and pass the address to the function
- being called. */
- rtx copy;
-
- if (TYPE_SIZE (type) == 0
- || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+#ifdef FUNCTION_ARG_CALLEE_COPIES
+ if (FUNCTION_ARG_CALLEE_COPIES (args_so_far, TYPE_MODE (type), type,
+ argpos < n_named_args)
+ /* If it's in a register, we must make a copy of it too. */
+ /* ??? Is this a sufficient test? Is there a better one? */
+ && !(TREE_CODE (args[i].tree_value) == VAR_DECL
+ && REG_P (DECL_RTL (args[i].tree_value))))
{
- /* This is a variable-sized object. Make space on the stack
- for it. */
- rtx size_rtx = expr_size (TREE_VALUE (p));
-
- if (old_stack_level == 0)
- {
- emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
- old_pending_adj = pending_stack_adjust;
- pending_stack_adjust = 0;
- }
-
- copy = gen_rtx (MEM, BLKmode,
- allocate_dynamic_stack_space (size_rtx, NULL_RTX,
- TYPE_ALIGN (type)));
+ args[i].tree_value = build1 (ADDR_EXPR,
+ build_pointer_type (type),
+ args[i].tree_value);
+ type = build_pointer_type (type);
}
else
+#endif
{
- int size = int_size_in_bytes (type);
- copy = assign_stack_temp (TYPE_MODE (type), size, 1);
- }
+ /* We make a copy of the object and pass the address to the
+ function being called. */
+ rtx copy;
- store_expr (args[i].tree_value, copy, 0);
+ if (TYPE_SIZE (type) == 0
+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ {
+ /* This is a variable-sized object. Make space on the stack
+ for it. */
+ rtx size_rtx = expr_size (TREE_VALUE (p));
+
+ if (old_stack_level == 0)
+ {
+ emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
+ old_pending_adj = pending_stack_adjust;
+ pending_stack_adjust = 0;
+ }
+
+ copy = gen_rtx (MEM, BLKmode,
+ allocate_dynamic_stack_space (size_rtx,
+ NULL_RTX,
+ TYPE_ALIGN (type)));
+ }
+ else
+ {
+ int size = int_size_in_bytes (type);
+ copy = assign_stack_temp (TYPE_MODE (type), size, 1);
+ }
- args[i].tree_value = build1 (ADDR_EXPR, build_pointer_type (type),
- make_tree (type, copy));
- type = build_pointer_type (type);
+ store_expr (args[i].tree_value, copy, 0);
+
+ args[i].tree_value = build1 (ADDR_EXPR,
+ build_pointer_type (type),
+ make_tree (type, copy));
+ type = build_pointer_type (type);
+ }
}
-#endif
+#endif /* FUNCTION_ARG_PASS_BY_REFERENCE */
mode = TYPE_MODE (type);