public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] strlen: fold strstr() even if the length isn't previously known [PR96601]
@ 2023-09-04 18:53 Hamza Mahfooz
  2023-09-04 18:53 ` [PATCH 2/2] strlen: call handle_builtin_strlen() from fold_strstr_to_strncmp() Hamza Mahfooz
  0 siblings, 1 reply; 2+ messages in thread
From: Hamza Mahfooz @ 2023-09-04 18:53 UTC (permalink / raw)
  To: gcc-patches
  Cc: Jeff Law, Ian Lance Taylor, Richard Biener, Prathamesh Kulkarni,
	Jakub Jelinek, Aldy Hernandez, Martin Sebor, Hamza Mahfooz

Currently, we give up in fold_strstr_to_strncmp() if the length of the
the second argument to strstr() isn't known to us by the time we hit
that function. However, we can instead insert a strlen() in ourselves
and continue trying to fold strstr() into strlen()+strncmp().

	PR tree-optimization/96601

gcc/ChangeLog:

	* tree-ssa-strlen.cc (fold_strstr_to_strncmp): If arg1_len == NULL,
	insert a strlen() for strstr()'s arg1 and use it as arg1_len.

gcc/testsuite/ChangeLog:

	* gcc.dg/strlenopt-30.c: Modify 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 |  5 +-
 gcc/tree-ssa-strlen.cc              | 81 ++++++++++++++++-------------
 2 files changed, 45 insertions(+), 41 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c b/gcc/testsuite/gcc.dg/strlenopt-30.c
index 2a3098ba96f..1ee814048c1 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-30.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-30.c
@@ -38,9 +38,6 @@ void f5(char *s)
     foo_f5();
 }
 
-/* Do not perform transform, since strlen (t)
-   is unknown.  */
-
 __attribute__((no_icf))
 _Bool f6(char *s, char *t)
 {
@@ -60,4 +57,4 @@ _Bool f7(char *s)
   return (t1 == s);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen1" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 6 "strlen1" } } */
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index 8b7ef919826..b0ebbb0db62 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -5273,6 +5273,7 @@ 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);
 
 	  if (idx)
 	    {
@@ -5286,51 +5287,57 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
 		}
 	    }
 
-	  if (arg1_len != NULL_TREE)
+	  if (arg1_len == NULL_TREE)
 	    {
-	      gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
-	      tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
+	      tree strlen_decl = builtin_decl_explicit (BUILT_IN_STRLEN);
+	      gcall *strlen_call = gimple_build_call (strlen_decl, 1, arg1);
+	      tree strlen_lhs = make_ssa_name (size_type_node, strlen_call);
+
+	      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;
+	    }
+	  else if (!is_gimple_val (arg1_len))
+	    {
+	      tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
+	      gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
+							arg1_len);
+	      gsi_insert_before (&gsi, arg1_stmt, GSI_SAME_STMT);
+	      arg1_len = arg1_len_tmp;
+	    }
 
-	      if (!is_gimple_val (arg1_len))
+	  tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
+	  gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
+						   arg0, arg1, arg1_len);
+	  tree strncmp_lhs = make_ssa_name (integer_type_node);
+	  gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
+	  gimple_call_set_lhs (strncmp_call, strncmp_lhs);
+	  gsi_remove (&gsi, true);
+	  gsi_insert_before (&gsi, strncmp_call, GSI_SAME_STMT);
+	  tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
+
+	  if (is_gimple_assign (stmt))
+	    {
+	      if (gimple_assign_rhs_code (stmt) == COND_EXPR)
 		{
-		  tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
-		  gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
-							    arg1_len);
-		  gsi_insert_before (&gsi, arg1_stmt, GSI_SAME_STMT);
-		  arg1_len = arg1_len_tmp;
-		}
-
-	      gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
-						      arg0, arg1, arg1_len);
-	      tree strncmp_lhs = make_ssa_name (integer_type_node);
-	      gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
-	      gimple_call_set_lhs (strncmp_call, strncmp_lhs);
-	      gsi_remove (&gsi, true);
-	      gsi_insert_before (&gsi, strncmp_call, GSI_SAME_STMT);
-	      tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
-
-	      if (is_gimple_assign (stmt))
-		{
-		  if (gimple_assign_rhs_code (stmt) == COND_EXPR)
-		    {
-		      tree cond = gimple_assign_rhs1 (stmt);
-		      TREE_OPERAND (cond, 0) = strncmp_lhs;
-		      TREE_OPERAND (cond, 1) = zero;
-		    }
-		  else
-		    {
-		      gimple_assign_set_rhs1 (stmt, strncmp_lhs);
-		      gimple_assign_set_rhs2 (stmt, zero);
-		    }
+		  tree cond = gimple_assign_rhs1 (stmt);
+		  TREE_OPERAND (cond, 0) = strncmp_lhs;
+		  TREE_OPERAND (cond, 1) = zero;
 		}
 	      else
 		{
-		  gcond *cond = as_a<gcond *> (stmt);
-		  gimple_cond_set_lhs (cond, strncmp_lhs);
-		  gimple_cond_set_rhs (cond, zero);
+		  gimple_assign_set_rhs1 (stmt, strncmp_lhs);
+		  gimple_assign_set_rhs2 (stmt, zero);
 		}
-	      update_stmt (stmt);
 	    }
+	  else
+	    {
+	      gcond *cond = as_a<gcond *> (stmt);
+	      gimple_cond_set_lhs (cond, strncmp_lhs);
+	      gimple_cond_set_rhs (cond, zero);
+	    }
+	  update_stmt (stmt);
 	}
     }
 }
-- 
2.42.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH 2/2] strlen: call handle_builtin_strlen() from fold_strstr_to_strncmp()
  2023-09-04 18:53 [PATCH 1/2] strlen: fold strstr() even if the length isn't previously known [PR96601] Hamza Mahfooz
@ 2023-09-04 18:53 ` Hamza Mahfooz
  0 siblings, 0 replies; 2+ messages in thread
From: Hamza Mahfooz @ 2023-09-04 18:53 UTC (permalink / raw)
  To: gcc-patches
  Cc: Jeff Law, Ian Lance Taylor, Richard Biener, Prathamesh Kulkarni,
	Jakub Jelinek, Aldy Hernandez, Martin Sebor, Hamza Mahfooz

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(-)

diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c b/gcc/testsuite/gcc.dg/strlenopt-30.c
index 1ee814048c1..de51a66383b 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-30.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-30.c
@@ -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" } } */
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index b0ebbb0db62..8ec6ddbc7c0 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -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 ();
-- 
2.42.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-09-04 18:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-04 18:53 [PATCH 1/2] strlen: fold strstr() even if the length isn't previously known [PR96601] Hamza Mahfooz
2023-09-04 18:53 ` [PATCH 2/2] strlen: call handle_builtin_strlen() from fold_strstr_to_strncmp() Hamza Mahfooz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).