Optimize strchr (s, 0) to s + strlen (s).
Optimize strchr (s, 0) to s + strlen (s). strchr (s, 0) appears a common idiom for finding the end of a string, however it is not a very efficient way of doing so. Strlen is a much simpler operation which is significantly faster (eg. on x86 strlen is 50% faster for strings of 8 bytes and about twice as fast as strchr on strings of 1KB). gcc/ * gimple-fold.c (gimple_fold_builtin_strchr): New function to optimize strchr (s, 0) to strlen. (gimple_fold_builtin): Add BUILT_IN_STRCHR case. testsuite/ * gcc.dg/strlenopt-20.c: Update test. * gcc.dg/strlenopt-21.c: Likewise. * gcc.dg/strlenopt-22.c: Likewise. * gcc.dg/strlenopt-22g.c: Likewise. * gcc.dg/strlenopt-26.c: Likewise. * gcc.dg/strlenopt-5.c: Likewise. * gcc.dg/strlenopt-7.c: Likewise. * gcc.dg/strlenopt-9.c: Likewise. From-SVN: r240568
This commit is contained in:
parent
1b4be62ad3
commit
912d9ec300
@ -1,3 +1,10 @@
|
||||
2016-09-28 Wilco Dijkstra <wdijkstr@arm.com>
|
||||
|
||||
PR tree-optimization/61056
|
||||
* gimple-fold.c (gimple_fold_builtin_strchr):
|
||||
New function to optimize strchr (s, 0) to strlen.
|
||||
(gimple_fold_builtin): Add BUILT_IN_STRCHR case.
|
||||
|
||||
2016-09-27 Robin Dapp <rdapp@linux.vnet.ibm.com>
|
||||
|
||||
PR tree-optimization/77724
|
||||
|
@ -1457,6 +1457,55 @@ gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Simplify strchr (str, 0) into str + strlen (str).
|
||||
In general strlen is significantly faster than strchr
|
||||
due to being a simpler operation. */
|
||||
static bool
|
||||
gimple_fold_builtin_strchr (gimple_stmt_iterator *gsi)
|
||||
{
|
||||
gimple *stmt = gsi_stmt (*gsi);
|
||||
tree str = gimple_call_arg (stmt, 0);
|
||||
tree c = gimple_call_arg (stmt, 1);
|
||||
location_t loc = gimple_location (stmt);
|
||||
|
||||
if (optimize_function_for_size_p (cfun))
|
||||
return false;
|
||||
|
||||
if (!integer_zerop (c) || !gimple_call_lhs (stmt))
|
||||
return false;
|
||||
|
||||
tree len;
|
||||
tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
|
||||
|
||||
if (!strlen_fn)
|
||||
return false;
|
||||
|
||||
/* Create newstr = strlen (str). */
|
||||
gimple_seq stmts = NULL;
|
||||
gimple *new_stmt = gimple_build_call (strlen_fn, 1, str);
|
||||
gimple_set_location (new_stmt, loc);
|
||||
if (gimple_in_ssa_p (cfun))
|
||||
len = make_ssa_name (size_type_node);
|
||||
else
|
||||
len = create_tmp_reg (size_type_node);
|
||||
gimple_call_set_lhs (new_stmt, len);
|
||||
gimple_seq_add_stmt_without_update (&stmts, new_stmt);
|
||||
|
||||
/* Create (str p+ strlen (str)). */
|
||||
new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
|
||||
POINTER_PLUS_EXPR, str, len);
|
||||
gimple_seq_add_stmt_without_update (&stmts, new_stmt);
|
||||
gsi_replace_with_seq_vops (gsi, stmts);
|
||||
/* gsi now points at the assignment to the lhs, get a
|
||||
stmt iterator to the strlen.
|
||||
??? We can't use gsi_for_stmt as that doesn't work when the
|
||||
CFG isn't built yet. */
|
||||
gimple_stmt_iterator gsi2 = *gsi;
|
||||
gsi_prev (&gsi2);
|
||||
fold_stmt (&gsi2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Simplify a call to the strcat builtin. DST and SRC are the arguments
|
||||
to the call.
|
||||
|
||||
@ -2898,6 +2947,8 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi)
|
||||
gimple_call_arg (stmt, 1));
|
||||
case BUILT_IN_STRNCAT:
|
||||
return gimple_fold_builtin_strncat (gsi);
|
||||
case BUILT_IN_STRCHR:
|
||||
return gimple_fold_builtin_strchr (gsi);
|
||||
case BUILT_IN_FPUTS:
|
||||
return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
|
||||
gimple_call_arg (stmt, 1), false);
|
||||
|
@ -1,3 +1,14 @@
|
||||
2016-09-28 Wilco Dijkstra <wdijkstr@arm.com>
|
||||
|
||||
* gcc.dg/strlenopt-20.c: Update test.
|
||||
* gcc.dg/strlenopt-21.c: Likewise.
|
||||
* gcc.dg/strlenopt-22.c: Likewise.
|
||||
* gcc.dg/strlenopt-22g.c: Likewise.
|
||||
* gcc.dg/strlenopt-26.c: Likewise.
|
||||
* gcc.dg/strlenopt-5.c: Likewise.
|
||||
* gcc.dg/strlenopt-7.c: Likewise.
|
||||
* gcc.dg/strlenopt-9.c: Likewise.
|
||||
|
||||
2016-09-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* g++.dg/cpp1z/feat-cxx1z.C: Add __cpp_capture_star_this test.
|
||||
|
@ -86,9 +86,9 @@ main ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
|
||||
|
@ -57,9 +57,9 @@ main ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
|
||||
|
@ -31,9 +31,9 @@ main ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
|
||||
|
@ -5,9 +5,9 @@
|
||||
#define USE_GNU
|
||||
#include "strlenopt-22.c"
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */
|
||||
|
@ -21,4 +21,5 @@ main (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
|
@ -48,9 +48,9 @@ main ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
|
||||
|
@ -40,11 +40,11 @@ main ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "\\*r_\[0-9\]* = 0;" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "return 3;" 1 "optimized" } } */
|
||||
|
@ -98,10 +98,10 @@ main ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 5 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 3 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "return 4;" 1 "optimized" } } */
|
||||
|
Loading…
x
Reference in New Issue
Block a user