diff options
author | Martin Liska <mliska@suse.cz> | 2019-05-02 09:57:38 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2019-05-02 07:57:38 +0000 |
commit | 786e0e5239529de9a4254fe8411a0e8f843e721a (patch) | |
tree | 8b319e19012eea14cba954edfd1ac8b95a7a6ff3 /gcc | |
parent | 06ceaa1d78d586eba492699075a8dee31ab3a3e8 (diff) | |
download | gcc-786e0e5239529de9a4254fe8411a0e8f843e721a.zip gcc-786e0e5239529de9a4254fe8411a0e8f843e721a.tar.gz gcc-786e0e5239529de9a4254fe8411a0e8f843e721a.tar.bz2 |
Prefer to use strlen call instead of inline expansion (PR target/88809).
2019-05-02 Martin Liska <mliska@suse.cz>
PR target/88809
* config/i386/i386.c (ix86_expand_strlen): Use strlen call.
With -minline-all-stringops use inline expansion using 4B loop.
* doc/invoke.texi: Document the change of
-minline-all-stringops.
2019-05-02 Martin Liska <mliska@suse.cz>
PR target/88809
* gcc.target/i386/pr88809.c: New test.
* gcc.target/i386/pr88809-2.c: New test.
From-SVN: r270787
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 70 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr88809-2.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr88809.c | 9 |
6 files changed, 53 insertions, 54 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f6ccd9..1883e4d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-05-02 Martin Liska <mliska@suse.cz> + + PR target/88809 + * config/i386/i386.c (ix86_expand_strlen): Use strlen call. + With -minline-all-stringops use inline expansion using 4B loop. + * doc/invoke.texi: Document the change of + -minline-all-stringops. + 2019-05-01 Jeff Law <law@redhat.com> PR tree-optimization/88797 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 43ee776..e7ee83d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -28270,68 +28270,34 @@ ix86_expand_strlensi_unroll_1 (rtx out, rtx src, rtx align_rtx) bool ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align) { - rtx addr, scratch1, scratch2, scratch3, scratch4; - - /* The generic case of strlen expander is long. Avoid it's - expanding unless TARGET_INLINE_ALL_STRINGOPS. */ - - if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1 - && !TARGET_INLINE_ALL_STRINGOPS - && !optimize_insn_for_size_p () - && (!CONST_INT_P (align) || INTVAL (align) < 4)) - return false; - - addr = force_reg (Pmode, XEXP (src, 0)); - scratch1 = gen_reg_rtx (Pmode); - - if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1 - && !optimize_insn_for_size_p ()) - { +if (TARGET_UNROLL_STRLEN + && TARGET_INLINE_ALL_STRINGOPS + && eoschar == const0_rtx + && optimize > 1) + { + /* The generic case of strlen expander is long. Avoid it's + expanding unless TARGET_INLINE_ALL_STRINGOPS. */ + rtx addr = force_reg (Pmode, XEXP (src, 0)); /* Well it seems that some optimizer does not combine a call like - foo(strlen(bar), strlen(bar)); - when the move and the subtraction is done here. It does calculate - the length just once when these instructions are done inside of - output_strlen_unroll(). But I think since &bar[strlen(bar)] is - often used and I use one fewer register for the lifetime of - output_strlen_unroll() this is better. */ + foo(strlen(bar), strlen(bar)); + when the move and the subtraction is done here. It does calculate + the length just once when these instructions are done inside of + output_strlen_unroll(). But I think since &bar[strlen(bar)] is + often used and I use one fewer register for the lifetime of + output_strlen_unroll() this is better. */ emit_move_insn (out, addr); ix86_expand_strlensi_unroll_1 (out, src, align); /* strlensi_unroll_1 returns the address of the zero at the end of - the string, like memchr(), so compute the length by subtracting - the start address. */ + the string, like memchr(), so compute the length by subtracting + the start address. */ emit_insn (ix86_gen_sub3 (out, out, addr)); + return true; } else - { - rtx unspec; - - /* Can't use this if the user has appropriated eax, ecx, or edi. */ - if (fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) - return false; - /* Can't use this for non-default address spaces. */ - if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (src))) - return false; - - scratch2 = gen_reg_rtx (Pmode); - scratch3 = gen_reg_rtx (Pmode); - scratch4 = force_reg (Pmode, constm1_rtx); - - emit_move_insn (scratch3, addr); - eoschar = force_reg (QImode, eoschar); - - src = replace_equiv_address_nv (src, scratch3); - - /* If .md starts supporting :P, this can be done in .md. */ - unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (4, src, eoschar, align, - scratch4), UNSPEC_SCAS); - emit_insn (gen_strlenqi_1 (scratch1, scratch3, unspec)); - emit_insn (ix86_gen_one_cmpl2 (scratch2, scratch1)); - emit_insn (ix86_gen_add3 (out, scratch2, constm1_rtx)); - } - return true; + return false; } /* For given symbol (function) construct code to compute address of it's PLT diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 516eb24..de7e1aa 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -28506,8 +28506,9 @@ By default GCC inlines string operations only when the destination is known to be aligned to least a 4-byte boundary. This enables more inlining and increases code size, but may improve performance of code that depends on fast -@code{memcpy}, @code{strlen}, -and @code{memset} for short lengths. +@code{memcpy} and @code{memset} for short lengths. +The option enables inline expansion of @code{strlen} for all +pointer alignments. @item -minline-stringops-dynamically @opindex minline-stringops-dynamically diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 45b181a..30227ca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-05-02 Martin Liska <mliska@suse.cz> + + PR target/88809 + * gcc.target/i386/pr88809.c: New test. + * gcc.target/i386/pr88809-2.c: New test. + 2019-05-01 Dominique d'Humieres <dominiq@gcc.gnu.org> PR fortran/60144 diff --git a/gcc/testsuite/gcc.target/i386/pr88809-2.c b/gcc/testsuite/gcc.target/i386/pr88809-2.c new file mode 100644 index 0000000..b8ef51d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr88809-2.c @@ -0,0 +1,9 @@ +/* PR target/88809 */ +/* { dg-options "-Os" } */ + +unsigned int foo (const char *ptr) +{ + return __builtin_strlen (ptr); +} + +/* { dg-final { scan-assembler "call\[ \t\]strlen" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr88809.c b/gcc/testsuite/gcc.target/i386/pr88809.c new file mode 100644 index 0000000..20844dd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr88809.c @@ -0,0 +1,9 @@ +/* PR target/88809 */ +/* { dg-options "-O" } */ + +unsigned int foo (const char *ptr) +{ + return __builtin_strlen (ptr); +} + +/* { dg-final { scan-assembler "call\[ \t\]strlen" } } */ |