diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2001-01-12 21:58:56 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2001-01-12 21:58:56 +0000 |
commit | f474c6f8f92594e09a56c03cdd609d161e690bdd (patch) | |
tree | 7db1440305362aa4b11577379f87eec6ec050a30 /gcc/calls.c | |
parent | 7dd232a8824ac79a5d17641804ffe1a72f19c387 (diff) | |
download | gcc-f474c6f8f92594e09a56c03cdd609d161e690bdd.tar.gz |
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.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index ab6c5bb40e8..95dad19f6c1 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 |