[2/2] strlen: call handle_builtin_strlen() from fold_strstr_to_strncmp()
Checks
Commit Message
Currently, we are not saving the strlen() call we inserted for possible
future common subexpression elimination. Also, it's possible that we can
further fold that strlen() call. So, refactor handle_builtin_strlen()
so that it can be called from fold_strstr_to_strncmp().
gcc/ChangeLog:
* tree-ssa-strlen.cc (strlen_pass::handle_builtin_strlen):
Remove from class and mark as static.
(handle_builtin_strlen): Add parameter
"gimple_stmt_iterator gsi" and replace references of m_gsi
with gsi.
(fold_strstr_to_strncmp): Call handle_builtin_strlen().
(strlen_pass::check_and_optimize_call): Add m_gsi to the
handle_builtin_strlen() call.
gcc/testsuite/ChangeLog:
* gcc.dg/strlenopt-30.c: Add a test.
Signed-off-by: Hamza Mahfooz <someguy@effective-light.com>
---
Please push this for me if you think it looks good. Since, I don't have
write access to the repository.
---
gcc/testsuite/gcc.dg/strlenopt-30.c | 7 +++++++
gcc/tree-ssa-strlen.cc | 23 ++++++++++++-----------
2 files changed, 19 insertions(+), 11 deletions(-)
@@ -44,6 +44,12 @@ _Bool f6(char *s, char *t)
return __builtin_strstr (s, t) == s;
}
+__attribute__((no_icf))
+_Bool f6plus(char *s, char *t)
+{
+ return __builtin_strstr (s, t) == s && __builtin_strlen(t) > 10;
+}
+
/* Do not perform transform in this case, since
t1 doesn't have single use. */
@@ -57,4 +63,5 @@ _Bool f7(char *s)
return (t1 == s);
}
+/* { dg-final { scan-tree-dump-times "__builtin_strlen" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 6 "strlen1" } } */
@@ -252,7 +252,6 @@ public:
bool handle_assign (tree lhs, bool *zero_write);
bool handle_store (bool *zero_write);
void handle_pointer_plus ();
- void handle_builtin_strlen ();
void handle_builtin_strchr ();
void handle_builtin_strcpy (built_in_function);
void handle_integral_assign (bool *cleanup_eh);
@@ -2211,10 +2210,10 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool call_lhs,
the strlen call with the known value, otherwise remember that strlen
of the argument is stored in the lhs SSA_NAME. */
-void
-strlen_pass::handle_builtin_strlen ()
+static void
+handle_builtin_strlen (gimple_stmt_iterator gsi)
{
- gimple *stmt = gsi_stmt (m_gsi);
+ gimple *stmt = gsi_stmt (gsi);
tree lhs = gimple_call_lhs (stmt);
if (lhs == NULL_TREE)
@@ -2268,8 +2267,8 @@ strlen_pass::handle_builtin_strlen ()
if (bound)
rhs = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (rhs), rhs, bound);
- gimplify_and_update_call_from_tree (&m_gsi, rhs);
- stmt = gsi_stmt (m_gsi);
+ gimplify_and_update_call_from_tree (&gsi, rhs);
+ stmt = gsi_stmt (gsi);
update_stmt (stmt);
if (dump_file && (dump_flags & TDF_DETAILS) != 0)
{
@@ -2367,8 +2366,8 @@ strlen_pass::handle_builtin_strlen ()
}
if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (ret)))
ret = fold_convert_loc (loc, TREE_TYPE (lhs), ret);
- gimplify_and_update_call_from_tree (&m_gsi, ret);
- stmt = gsi_stmt (m_gsi);
+ gimplify_and_update_call_from_tree (&gsi, ret);
+ stmt = gsi_stmt (gsi);
update_stmt (stmt);
if (dump_file && (dump_flags & TDF_DETAILS) != 0)
{
@@ -5272,8 +5271,9 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
{
tree arg1 = gimple_call_arg (call_stmt, 1);
tree arg1_len = NULL_TREE;
- int idx = get_stridx (arg1, call_stmt);
gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
+again:
+ int idx = get_stridx (arg1, call_stmt);
if (idx)
{
@@ -5296,7 +5296,8 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
gimple_call_set_lhs (strlen_call, strlen_lhs);
gimple_set_vuse (strlen_call, gimple_vuse (call_stmt));
gsi_insert_before (&gsi, strlen_call, GSI_SAME_STMT);
- arg1_len = strlen_lhs;
+ handle_builtin_strlen (gsi_for_stmt (strlen_call));
+ goto again;
}
else if (!is_gimple_val (arg1_len))
{
@@ -5393,7 +5394,7 @@ strlen_pass::check_and_optimize_call (bool *zero_write)
{
case BUILT_IN_STRLEN:
case BUILT_IN_STRNLEN:
- handle_builtin_strlen ();
+ handle_builtin_strlen (m_gsi);
break;
case BUILT_IN_STRCHR:
handle_builtin_strchr ();