On Wed, Mar 14, 2018 at 01:54:39PM +0100, Martin Liška wrote:
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3651,13 +3651,24 @@ expand_builtin_memory_copy_args (tree dest, tree src,
tree len,
src_mem = get_memory_rtx (src, len);
set_mem_align (src_mem, src_align);
+ bool is_move_done;
+
/* Copy word part most expediently. */
This comment supposedly belongs right above the emit_block_move_hints call.
+ bool bail_out_libcall = endp == 1
+ && targetm.libc_func_speed ((int)BUILT_IN_MEMPCPY) == FAST_SPEED;
Formatting. && belongs below endp. So either:
bool bail_out_libcall
= (endp == 1
&& ...);
or
bool bail_out_libcall = false;
if (endp == 1
&& ...)
bail_out_libcall = true;
?
The variable is not named very well, shouldn't it be avoid_libcall or
something similar? Perhaps the variable should have a comment describing
what it is. Do you need separate argument for that bool and
is_move_done, rather than just the flag being that some pointer to bool is
non-NULL?
dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
CALL_EXPR_TAILCALL (exp)
&& (endp == 0 || target == const0_rtx)
? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
expected_align, expected_size,
- min_size, max_size, probable_max_size);
+ min_size, max_size, probable_max_size,
+ bail_out_libcall, &is_move_done);
+
+ /* Bail out when a mempcpy call would be expanded as libcall and when
+ we have a target that provides a fast implementation
+ of mempcpy routine. */
+ if (!is_move_done)
+ return NULL_RTX;
if (dest_addr == 0)
{
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2733,6 +2733,23 @@ ix86_using_red_zone (void)
&& (!cfun->machine->has_local_indirect_jump
|| cfun->machine->indirect_branch_type == indirect_branch_keep));
}
+
Missing function comment here. For target hooks, usually there is a copy of
the target.def comment, perhaps with further details on why it is overridden
and what it does.
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -384,6 +384,13 @@ enum excess_precision_type
EXCESS_PRECISION_TYPE_FAST
};
Missing comment describing what it is, plus it the enumerators are too
generic, if it is libc_speed enum, perhaps LIBC_FAST_SPEED etc.?
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1642,6 +1642,12 @@ no_c99_libc_has_function (enum function_class fn_class
ATTRIBUTE_UNUSED)
return false;
}
Again, missing function comment.
+enum libc_speed
+default_libc_func_speed (int)
+{
+ return UNKNOWN_SPEED;
+}
+
--- a/gcc/testsuite/gcc.dg/string-opt-1.c
+++ b/gcc/testsuite/gcc.dg/string-opt-1.c
@@ -48,5 +48,5 @@ main (void)
return 0;
}
-/* { dg-final { scan-assembler-not "\<mempcpy\>" } } */
-/* { dg-final { scan-assembler "memcpy" } } */
+/* { dg-final { scan-assembler-not "\<mempcpy\>" { target { i?86-*-*
x86_64-*-* } } } } */
+/* { dg-final { scan-assembler "memcpy" { target { ! { i?86-*-* x86_64-*-* }
} } } } */
First of all, I don't really understand this, I'd expect both the
two old dg-final lines to be used as is for non-x86 targets and another two
for x86_64, and more importantly, the target hook is only for glibc, not for
musl/bionic etc., nor for non-linux, so you probably need some effective
target for it for whether it is glibc rather than musl/bionic, and use
...-*-linux* and ...-*-gnu* etc. rather than ...-*-*. Or tweak the dg-fianl
patterns so that it succeeds on both variants of the target hook, but then
does the test test anything at all?