diff options
author | Martin Liska <mliska@suse.cz> | 2019-05-20 09:55:00 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2019-05-20 07:55:00 +0000 |
commit | db91c7cf3d97a169d4e1c463d87a9f2007c40761 (patch) | |
tree | 11aa3bde6da1520b48d1a2a0cbf8e580e67e0c11 /gcc | |
parent | 03105885b1502a971955908255c722df5be0dafd (diff) | |
download | gcc-db91c7cf3d97a169d4e1c463d87a9f2007c40761.zip gcc-db91c7cf3d97a169d4e1c463d87a9f2007c40761.tar.gz gcc-db91c7cf3d97a169d4e1c463d87a9f2007c40761.tar.bz2 |
Come up with hook libc_has_fast_function (PR middle-end/90263).
2019-05-20 Martin Liska <mliska@suse.cz>
PR middle-end/90263
* builtins.c (expand_builtin_memory_copy_args): When having a
target with fast mempcpy implementation do now use memcpy.
* config/i386/i386.c (ix86_libc_has_fast_function): New.
(TARGET_LIBC_HAS_FAST_FUNCTION): Likewise.
* doc/tm.texi: Likewise.
* doc/tm.texi.in: Likewise.
* target.def:
* expr.c (emit_block_move_hints): Add 2 new arguments.
* expr.h (emit_block_move_hints): Bail out when libcall
to memcpy would be used.
2019-05-20 Martin Liska <mliska@suse.cz>
PR middle-end/90263
* gcc.c-torture/compile/pr90263.c: New test.
* lib/target-supports.exp: Add check_effective_target_glibc.
From-SVN: r271400
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/builtins.c | 17 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 15 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 5 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 2 | ||||
-rw-r--r-- | gcc/expr.c | 13 | ||||
-rw-r--r-- | gcc/expr.h | 4 | ||||
-rw-r--r-- | gcc/target.def | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr90263.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/lib/target-supports.exp | 11 |
11 files changed, 100 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4f0e2d..68564af 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,19 @@ 2019-05-20 Martin Liska <mliska@suse.cz> + PR middle-end/90263 + * builtins.c (expand_builtin_memory_copy_args): When having a + target with fast mempcpy implementation do now use memcpy. + * config/i386/i386.c (ix86_libc_has_fast_function): New. + (TARGET_LIBC_HAS_FAST_FUNCTION): Likewise. + * doc/tm.texi: Likewise. + * doc/tm.texi.in: Likewise. + * target.def: + * expr.c (emit_block_move_hints): Add 2 new arguments. + * expr.h (emit_block_move_hints): Bail out when libcall + to memcpy would be used. + +2019-05-20 Martin Liska <mliska@suse.cz> + * profile-count.c: Add vertical spacing in order to separate functions. * profile-count.h: Likewise. diff --git a/gcc/builtins.c b/gcc/builtins.c index 0456a9e..3f32754 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -3839,6 +3839,8 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len, unsigned HOST_WIDE_INT max_size; unsigned HOST_WIDE_INT probable_max_size; + bool is_move_done; + /* If DEST is not a pointer type, call the normal function. */ if (dest_align == 0) return NULL_RTX; @@ -3888,11 +3890,22 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len, if (CALL_EXPR_TAILCALL (exp) && (retmode == RETURN_BEGIN || target == const0_rtx)) method = BLOCK_OP_TAILCALL; - if (retmode == RETURN_END && target != const0_rtx) + bool use_mempcpy_call = (targetm.libc_has_fast_function (BUILT_IN_MEMPCPY) + && retmode == RETURN_END + && target != const0_rtx); + if (use_mempcpy_call) method = BLOCK_OP_NO_LIBCALL_RET; dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, method, expected_align, expected_size, - min_size, max_size, probable_max_size); + min_size, max_size, probable_max_size, + use_mempcpy_call, &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 == pc_rtx) return NULL_RTX; diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index d3eb7c8..384c633 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -23063,6 +23063,21 @@ ix86_run_selftests (void) #define TARGET_GET_MULTILIB_ABI_NAME \ ix86_get_multilib_abi_name +static bool ix86_libc_has_fast_function (int fcode) +{ +#ifdef OPTION_GLIBC + if (OPTION_GLIBC) + return (built_in_function)fcode == BUILT_IN_MEMPCPY; + else + return false; +#else + return false; +#endif +} + +#undef TARGET_LIBC_HAS_FAST_FUNCTION +#define TARGET_LIBC_HAS_FAST_FUNCTION ix86_libc_has_fast_function + #if CHECKING_P #undef TARGET_RUN_TARGET_SELFTESTS #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 8c8978b..0941039 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5594,6 +5594,11 @@ This hook determines whether a function from a class of functions @var{fn_class} is present at the runtime. @end deftypefn +@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FAST_FUNCTION (int @var{fcode}) +This hook determines whether a function from a class of functions +@var{fn_class} has a fast implementation. +@end deftypefn + @defmac NEXT_OBJC_RUNTIME Set this macro to 1 to use the "NeXT" Objective-C message sending conventions by default. This calling convention involves passing the object, the selector diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index fe1194e..17560fc 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3991,6 +3991,8 @@ macro, a reasonable default is used. @hook TARGET_LIBC_HAS_FUNCTION +@hook TARGET_LIBC_HAS_FAST_FUNCTION + @defmac NEXT_OBJC_RUNTIME Set this macro to 1 to use the "NeXT" Objective-C message sending conventions by default. This calling convention involves passing the object, the selector @@ -1561,12 +1561,16 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method, unsigned int expected_align, HOST_WIDE_INT expected_size, unsigned HOST_WIDE_INT min_size, unsigned HOST_WIDE_INT max_size, - unsigned HOST_WIDE_INT probable_max_size) + unsigned HOST_WIDE_INT probable_max_size, + bool bail_out_libcall, bool *is_move_done) { int may_use_call; rtx retval = 0; unsigned int align; + if (is_move_done) + *is_move_done = true; + gcc_assert (size); if (CONST_INT_P (size) && INTVAL (size) == 0) return 0; @@ -1628,6 +1632,13 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method, && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)) && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (y))) { + if (bail_out_libcall) + { + if (is_move_done) + *is_move_done = false; + return retval; + } + if (may_use_call < 0) return pc_rtx; @@ -114,7 +114,9 @@ extern rtx emit_block_move_hints (rtx, rtx, rtx, enum block_op_methods, unsigned int, HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, - unsigned HOST_WIDE_INT); + unsigned HOST_WIDE_INT, + bool bail_out_libcall = false, + bool *is_move_done = NULL); extern rtx emit_block_cmp_hints (rtx, rtx, rtx, tree, rtx, bool, by_pieces_constfn, void *); extern bool emit_storent_insn (rtx to, rtx from); diff --git a/gcc/target.def b/gcc/target.def index 66cee07..23e260c 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2547,6 +2547,13 @@ DEFHOOK bool, (enum function_class fn_class), default_libc_has_function) +DEFHOOK +(libc_has_fast_function, + "This hook determines whether a function from a class of functions\n\ +@var{fn_class} has a fast implementation.", + bool, (int fcode), + default_libc_has_fast_function) + /* True if new jumps cannot be created, to replace existing ones or not, at the current point in the compilation. */ DEFHOOK diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ecb4d68..7b3bf73 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-05-20 Martin Liska <mliska@suse.cz> + + PR middle-end/90263 + * gcc.c-torture/compile/pr90263.c: New test. + * lib/target-supports.exp: Add check_effective_target_glibc. + 2019-05-20 Richard Biener <rguenther@suse.de> PR testsuite/90518 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr90263.c b/gcc/testsuite/gcc.c-torture/compile/pr90263.c new file mode 100644 index 0000000..df3ab0f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr90263.c @@ -0,0 +1,10 @@ +/* PR middle-end/90263 */ +/* { dg-require-effective-target glibc } */ + +int *f (int *p, int *q, long n) +{ + return __builtin_mempcpy (p, q, n); +} + +/* { dg-final { scan-assembler "mempcpy" { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler "memcpy" { target { ! { i?86-*-* x86_64-*-* } } } } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 63bc2cc..3bd6e81 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -9313,6 +9313,17 @@ proc check_effective_target_arm_v8_3a_complex_neon_hw { } { } [add_options_for_arm_v8_3a_complex_neon ""]] } +# Returns 1 if the target is using glibc, 0 otherwise. + +proc check_effective_target_glibc { } { + return [check_no_compiler_messages glibc_object assembly { + #include <stdlib.h> + #if !defined(__GLIBC__) + #error undefined + #endif + }] +} + # Return 1 if the target plus current options supports a vector # complex addition with rotate of half and single float modes, 0 otherwise. # |