diff options
author | Doug Evans <dje@gnu.org> | 1993-04-19 19:24:23 +0000 |
---|---|---|
committer | Doug Evans <dje@gnu.org> | 1993-04-19 19:24:23 +0000 |
commit | 5e0de251204954b4a332a2ed7417623ed826de3e (patch) | |
tree | cfbd4116ad8dc8f6ccdd649076ec02873f0c1902 | |
parent | fd6b2a6d3e5054e023b85c67e88910a4406d0935 (diff) | |
download | gcc-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.c | 75 |
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); |