From d5f9786fae594d6d9f449e98620f3009d9a6710d Mon Sep 17 00:00:00 2001 From: kenner Date: Sat, 3 May 2003 14:25:22 +0000 Subject: * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66429 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/expr.c | 66 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 27 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index bc316b32f56..b64319a08a7 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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 -- cgit v1.2.1