Message ID | 515082C3.9070602@netcologne.de |
---|---|
State | New |
Headers | show |
On Mon, Mar 25, 2013 at 7:00 PM, Thomas Koenig <tkoenig@netcologne.de> wrote: > Hello world, > > this patch uses memcpy() directly when comparing two kind=1 strings of > equal and constant lengths. The test case modification depends > on the previous patch at > > http://gcc.gnu.org/ml/gcc-patches/2013-03/msg00996.html > > for setting the string lengths for substrings. > > Regression-tested. No extra test case because the original test > cases have to be modified to avoid failure, and test the new > feature. OK for trunk after committing the patch above? > > 2013-03-25 Thomas Koenig <tkoenig@gcc.gnu.org> > > * trans-expr.c (build_memcmp_call): New function. > (gfc_build_compare_string): If the kind=1 strings to be > compared have constant and equal lengths, use > memcmp(). > > 2013-03-25 Thomas Koenig <tkoenig@gcc.gnu.org> > > * gfortran.dg/character_comparison_3.f90: Adjust for use of memcmp > for constant and equal string lengths. > * gfortran.dg/character_comparison_5.f90: Likewise. Ok. I think the same optimization could be done for kind=4 strings as well, but nobody probably uses those anyway..
On Tue, Mar 26, 2013 at 11:53:27PM +0200, Janne Blomqvist wrote: > On Mon, Mar 25, 2013 at 7:00 PM, Thomas Koenig <tkoenig@netcologne.de> wrote: > > Hello world, > > > > this patch uses memcpy() directly when comparing two kind=1 strings of > > equal and constant lengths. The test case modification depends > > on the previous patch at > > Could you omit of equal lengths part? Do memcmp with minimum of lengths and if not equal call compare_string for suffixes. > > http://gcc.gnu.org/ml/gcc-patches/2013-03/msg00996.html > > > > for setting the string lengths for substrings. > > > > Regression-tested. No extra test case because the original test > > cases have to be modified to avoid failure, and test the new > > feature. OK for trunk after committing the patch above? > > > > 2013-03-25 Thomas Koenig <tkoenig@gcc.gnu.org> > > > > * trans-expr.c (build_memcmp_call): New function. > > (gfc_build_compare_string): If the kind=1 strings to be > > compared have constant and equal lengths, use > > memcmp(). > > > > 2013-03-25 Thomas Koenig <tkoenig@gcc.gnu.org> > > > > * gfortran.dg/character_comparison_3.f90: Adjust for use of memcmp > > for constant and equal string lengths. > > * gfortran.dg/character_comparison_5.f90: Likewise. > > Ok. I think the same optimization could be done for kind=4 strings as > well, but nobody probably uses those anyway.. > > > -- > Janne Blomqvist
Index: fortran/trans-expr.c =================================================================== --- fortran/trans-expr.c (Revision 196748) +++ fortran/trans-expr.c (Arbeitskopie) @@ -2655,6 +2665,32 @@ gfc_optimize_len_trim (tree len, tree str, int kin return -1; } +/* Helper to build a call to memcmp. */ + +static tree +build_memcmp_call (tree s1, tree s2, tree n) +{ + tree tmp; + + if (!POINTER_TYPE_P (TREE_TYPE (s1))) + s1 = gfc_build_addr_expr (pvoid_type_node, s1); + else + s1 = fold_convert (pvoid_type_node, s1); + + if (!POINTER_TYPE_P (TREE_TYPE (s2))) + s2 = gfc_build_addr_expr (pvoid_type_node, s2); + else + s2 = fold_convert (pvoid_type_node, s2); + + n = fold_convert (size_type_node, n); + + tmp = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_MEMCMP), + 3, s1, s2, n); + + return fold_convert (integer_type_node, tmp); +} + /* Compare two strings. If they are all single characters, the result is the subtraction of them. Otherwise, we build a library call. */ @@ -2698,7 +2734,13 @@ gfc_build_compare_string (tree len1, tree str1, tr /* Build a call for the comparison. */ if (kind == 1) - fndecl = gfor_fndecl_compare_string; + { + if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2) + && tree_int_cst_equal (len1, len2)) + return build_memcmp_call (str1, str2, len1); + else + fndecl = gfor_fndecl_compare_string; + } else if (kind == 4) fndecl = gfor_fndecl_compare_string_char4; else Index: testsuite/gfortran.dg/character_comparison_3.f90 =================================================================== --- testsuite/gfortran.dg/character_comparison_3.f90 (Revision 196748) +++ testsuite/gfortran.dg/character_comparison_3.f90 (Arbeitskopie) @@ -25,6 +25,7 @@ program main if (c(:k3) == c(:k44)) call abort end program main -! { dg-final { scan-tree-dump-times "gfortran_compare_string" 8 "original" } } +! { dg-final { scan-tree-dump-times "gfortran_compare_string" 6 "original" } } +! { dg-final { scan-tree-dump-times "__builtin_memcmp" 2 "original" } } ! { dg-final { cleanup-tree-dump "original" } } Index: testsuite/gfortran.dg/character_comparison_5.f90 =================================================================== --- testsuite/gfortran.dg/character_comparison_5.f90 (Revision 196748) +++ testsuite/gfortran.dg/character_comparison_5.f90 (Arbeitskopie) @@ -16,6 +16,6 @@ program main end program main ! { dg-final { scan-tree-dump-times "gfortran_concat_string" 0 "original" } } -! { dg-final { scan-tree-dump-times "gfortran_compare_string" 2 "original" } } +! { dg-final { scan-tree-dump-times "__builtin_memcmp" 2 "original" } } ! { dg-final { cleanup-tree-dump "original" } }