aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2001-01-12 21:58:56 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2001-01-12 21:58:56 +0000
commitf474c6f8f92594e09a56c03cdd609d161e690bdd (patch)
tree7db1440305362aa4b11577379f87eec6ec050a30 /gcc/calls.c
parent7dd232a8824ac79a5d17641804ffe1a72f19c387 (diff)
downloadgcc-f474c6f8f92594e09a56c03cdd609d161e690bdd.zip
gcc-f474c6f8f92594e09a56c03cdd609d161e690bdd.tar.gz
gcc-f474c6f8f92594e09a56c03cdd609d161e690bdd.tar.bz2
calls.c (emit_library_call_value_1): Add USEs and CLOBBERs to function usage for arguments passed by reference.
* calls.c (emit_library_call_value_1): Add USEs and CLOBBERs to function usage for arguments passed by reference. Optimize callee-copied arguments. * regmove.c (find_related_toplev): Find uses in function usage. (replace_in_call_usage): New function. (fixup_match_1): Call it. * cse.c (cse_insn): Canonicalize registers in function usage. * reload1.c (replace_pseudos_in_call_usage): New function. (reload): Call it. From-SVN: r38964
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index ab6c5bb..95dad19 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3676,16 +3676,44 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1))
{
- /* We do not support FUNCTION_ARG_CALLEE_COPIES here since it can
- be viewed as just an efficiency improvement. */
- rtx slot = assign_temp (type_for_mode (mode, 0), 0, 1, 1);
+ rtx slot;
+ int must_copy = 1
+#ifdef FUNCTION_ARG_CALLEE_COPIES
+ && ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode,
+ NULL_TREE, 1)
+#endif
+ ;
+
+ if (GET_MODE (val) == MEM && ! must_copy)
+ slot = val;
+ else if (must_copy)
+ {
+ slot = assign_temp (type_for_mode (mode, 0), 0, 1, 1);
+ emit_move_insn (slot, val);
+ }
+ else
+ {
+ tree type = type_for_mode (mode, 0);
+
+ slot = gen_rtx_MEM (Pmode,
+ expand_expr (build1 (ADDR_EXPR,
+ build_pointer_type
+ (type),
+ make_tree (type, val)),
+ NULL_RTX, VOIDmode, 0));
+ }
call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_USE (VOIDmode, slot),
call_fusage);
- emit_move_insn (slot, val);
- val = force_operand (XEXP (slot, 0), NULL_RTX);
+ if (must_copy)
+ call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_CLOBBER (VOIDmode,
+ slot),
+ call_fusage);
+
mode = Pmode;
+ val = force_operand (XEXP (slot, 0), NULL_RTX);
}
#endif