diff options
author | Olivier Hainque <hainque@act-europe.fr> | 2003-05-03 16:25:22 +0200 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2003-05-03 10:25:22 -0400 |
commit | ee9609391b6e1bd4d026b86cf79bced76e1baa5b (patch) | |
tree | 7ad4bd29e44c9c37b87311753f154d5fa72e515b /gcc/expr.c | |
parent | 3923e4102fcfa593de9148a4855ca54d8466fbe7 (diff) | |
download | gcc-ee9609391b6e1bd4d026b86cf79bced76e1baa5b.zip gcc-ee9609391b6e1bd4d026b86cf79bced76e1baa5b.tar.gz gcc-ee9609391b6e1bd4d026b86cf79bced76e1baa5b.tar.bz2 |
emit-rtl.c (last_call_insn, [...]): New functions.
* emit-rtl.c (last_call_insn, add_function_usage_to): New functions.
* rtl.h (last_call_insn, add_function_usage_to): New prototypes.
* builtins.c (expand_builtin_apply): Use the new emit-rtl functions.
* calls.c (emit_call_1): Likewise.
(expand_call): For calls initializing constant memory, replace
emission of standalone mem /u clobber with function usage entry.
* expr.c (emit_block_move_via_libcall): Likewise.
* cse.c (count_reg_usage, case EXPR_LIST): New case.
* flow.c (propagate_one_insn): Pass entire operand of
CALL_INSN_FUNCTION_USAGE to mark_used_regs.
* integrate.c (try_constants): For CALL_INSNs, substitute constants
within the FUNCTION_USAGE also.
* loop.c (prescan_loop): Note clobbers of const mem mentioned in
FUNCTION_USAGE lists.
* reload1.c (replace_pseudos_in): Renamed.
(reload): Use it for clobbers surviving until the end of the reload.
From-SVN: r66429
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 66 |
1 files changed, 39 insertions, 27 deletions
@@ -1839,16 +1839,16 @@ emit_block_move_via_movstr (x, y, size, align) rtx x, y, size; unsigned int align; { - /* Try the most limited insn first, because there's no point - including more than one in the machine description unless - the more limited one has some advantage. */ - rtx opalign = GEN_INT (align / BITS_PER_UNIT); enum machine_mode mode; /* Since this is a move insn, we don't care about volatility. */ volatile_ok = 1; + /* Try the most limited insn first, because there's no point + including more than one in the machine description unless + the more limited one has some advantage. */ + for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) { @@ -1908,38 +1908,48 @@ static rtx emit_block_move_via_libcall (dst, src, size) rtx dst, src, size; { + rtx dst_addr, src_addr; tree call_expr, arg_list, fn, src_tree, dst_tree, size_tree; enum machine_mode size_mode; rtx retval; /* DST, SRC, or SIZE may have been passed through protect_from_queue. - It is unsafe to save the value generated by protect_from_queue - and reuse it later. Consider what happens if emit_queue is - called before the return value from protect_from_queue is used. + It is unsafe to save the value generated by protect_from_queue and reuse + it later. Consider what happens if emit_queue is called before the + return value from protect_from_queue is used. - Expansion of the CALL_EXPR below will call emit_queue before - we are finished emitting RTL for argument setup. So if we are - not careful we could get the wrong value for an argument. + Expansion of the CALL_EXPR below will call emit_queue before we are + finished emitting RTL for argument setup. So if we are not careful we + could get the wrong value for an argument. - To avoid this problem we go ahead and emit code to copy X, Y & - SIZE into new pseudos. We can then place those new pseudos - into an RTL_EXPR and use them later, even after a call to + To avoid this problem we go ahead and emit code to copy the addresses of + DST and SRC and SIZE into new pseudos. We can then place those new + pseudos into an RTL_EXPR and use them later, even after a call to emit_queue. - Note this is not strictly needed for library calls since they - do not call emit_queue before loading their arguments. However, - we may need to have library calls call emit_queue in the future - since failing to do so could cause problems for targets which - define SMALL_REGISTER_CLASSES and pass arguments in registers. */ + Note this is not strictly needed for library calls since they do not call + emit_queue before loading their arguments. However, we may need to have + library calls call emit_queue in the future since failing to do so could + cause problems for targets which define SMALL_REGISTER_CLASSES and pass + arguments in registers. */ + + dst_addr = copy_to_mode_reg (Pmode, XEXP (dst, 0)); + src_addr = copy_to_mode_reg (Pmode, XEXP (src, 0)); + +#ifdef POINTERS_EXTEND_UNSIGNED + dst_addr = convert_memory_address (ptr_mode, dst_addr); + src_addr = convert_memory_address (ptr_mode, src_addr); +#endif - dst = copy_to_mode_reg (Pmode, XEXP (dst, 0)); - src = copy_to_mode_reg (Pmode, XEXP (src, 0)); + dst_tree = make_tree (ptr_type_node, dst_addr); + src_tree = make_tree (ptr_type_node, src_addr); if (TARGET_MEM_FUNCTIONS) size_mode = TYPE_MODE (sizetype); else size_mode = TYPE_MODE (unsigned_type_node); + size = convert_to_mode (size_mode, size, 1); size = copy_to_mode_reg (size_mode, size); @@ -1951,8 +1961,6 @@ emit_block_move_via_libcall (dst, src, size) For convenience, we generate the call to bcopy this way as well. */ - dst_tree = make_tree (ptr_type_node, dst); - src_tree = make_tree (ptr_type_node, src); if (TARGET_MEM_FUNCTIONS) size_tree = make_tree (sizetype, size); else @@ -1979,13 +1987,17 @@ emit_block_move_via_libcall (dst, src, size) retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0); - /* If we are initializing a readonly value, show the above call - clobbered it. Otherwise, a load from it may erroneously be - hoisted from a loop. */ + /* If we are initializing a readonly value, show the above call clobbered + it. Otherwise, a load from it may erroneously be hoisted from a loop, or + the delay slot scheduler might overlook conflicts and take nasty + decisions. */ if (RTX_UNCHANGING_P (dst)) - emit_insn (gen_rtx_CLOBBER (VOIDmode, dst)); + add_function_usage_to + (last_call_insn (), gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_CLOBBER (VOIDmode, dst), + NULL_RTX)); - return (TARGET_MEM_FUNCTIONS ? retval : NULL_RTX); + return TARGET_MEM_FUNCTIONS ? retval : NULL_RTX; } /* A subroutine of emit_block_move_via_libcall. Create the tree node |