]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
builtins.c (expand_builtin_strstr): New function.
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>
Wed, 1 Nov 2000 03:22:21 +0000 (03:22 +0000)
committerKaveh Ghazi <ghazi@gcc.gnu.org>
Wed, 1 Nov 2000 03:22:21 +0000 (03:22 +0000)
* builtins.c (expand_builtin_strstr): New function.
(expand_builtin): Handle BUILT_IN_STRSTR and BUILT_IN_STRCHR.

* builtins.def (BUILT_IN_STRSTR, BUILT_IN_STRCHR): New entries.

* c-common.c (c_common_nodes_and_builtins): Declare builtin strstr
and builtin strchr.

From-SVN: r37181

gcc/ChangeLog
gcc/builtins.c
gcc/builtins.def
gcc/c-common.c

index 750c1c2a2ba15699fc05a5ba0494a6b1324fd0e4..c89515b510902936bf38463108815d2c2025492b 100644 (file)
@@ -1,3 +1,13 @@
+2000-10-31  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * builtins.c (expand_builtin_strstr): New function.
+       (expand_builtin): Handle BUILT_IN_STRSTR and BUILT_IN_STRCHR.
+
+       * builtins.def (BUILT_IN_STRSTR, BUILT_IN_STRCHR): New entries.
+
+       * c-common.c (c_common_nodes_and_builtins): Declare builtin strstr
+       and builtin strchr.
+
 2000-10-31  Richard Henderson  <rth@redhat.com>
 
        * config/i386/i386.c (fcmov_comparison_operator): Check for
index 3304b68a46a81d26a677e4cfd492948c408c4f15..abb67476cd6d2da9887264c7f077f9d3b0d4b0f0 100644 (file)
@@ -108,6 +108,8 @@ static rtx expand_builtin_memset    PARAMS ((tree));
 static rtx expand_builtin_bzero                PARAMS ((tree));
 static rtx expand_builtin_strlen       PARAMS ((tree, rtx,
                                                 enum machine_mode));
+static rtx expand_builtin_strstr       PARAMS ((tree, rtx,
+                                                enum machine_mode));
 static rtx expand_builtin_alloca       PARAMS ((tree, rtx));
 static rtx expand_builtin_ffs          PARAMS ((tree, rtx, rtx));
 static rtx expand_builtin_frame_address        PARAMS ((tree));
@@ -1431,6 +1433,64 @@ expand_builtin_strlen (exp, target, mode)
     }
 }
 
+/* Expand a call to the strstr builtin.  Return 0 if we failed the
+   caller should emit a normal call, otherwise try to get the result
+   in TARGET, if convenient (and in mode MODE if that's convenient).  */
+
+static rtx
+expand_builtin_strstr (arglist, target, mode)
+     tree arglist;
+     rtx target;
+     enum machine_mode mode;
+{
+  if (arglist == 0
+      || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
+      || TREE_CHAIN (arglist) == 0
+      || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
+    return 0;
+  else
+    {
+      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
+      tree len = c_strlen (s2);
+
+      if (!len)
+       return 0;
+
+      switch (compare_tree_int (len, 1))
+        {
+       case -1: /* length is 0, return s1.  */
+         return expand_expr (s1, target, mode, EXPAND_NORMAL);
+       case 0: /* length is 1, return strchr(s1, s2[0]).  */
+         {
+           tree call_expr, fn = built_in_decls[BUILT_IN_STRCHR];
+
+           if (!fn)
+             return 0;
+           STRIP_NOPS (s2);
+           if (s2 && TREE_CODE (s2) == ADDR_EXPR)
+             s2 = TREE_OPERAND (s2, 0);
+
+           /* New argument list transforming strstr(s1, s2) to
+              strchr(s1, s2[0]).  */
+           arglist =
+             build_tree_list (NULL_TREE,
+                              build_int_2 (TREE_STRING_POINTER (s2)[0], 0));
+           arglist = tree_cons (NULL_TREE, s1, arglist);
+           call_expr = build1 (ADDR_EXPR,
+                               build_pointer_type (TREE_TYPE (fn)), fn);
+           call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
+                              call_expr, arglist, NULL_TREE);
+           TREE_SIDE_EFFECTS (call_expr) = 1;
+           return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
+         }
+       case 1: /* length is greater than 1, really call strstr.  */
+         return 0;
+       default:
+         abort();
+       }
+    }
+}
+
 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.  */
 static rtx
 expand_builtin_memcpy (arglist)
@@ -2475,6 +2535,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
          || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
          || fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
          || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
+         || fcode == BUILT_IN_STRSTR
          || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
          || fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
          || fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
@@ -2603,6 +2664,12 @@ expand_builtin (exp, target, subtarget, mode, ignore)
        return target;
       break;
       
+    case BUILT_IN_STRSTR:
+      target = expand_builtin_strstr (arglist, target, mode);
+      if (target)
+       return target;
+      break;
+      
     case BUILT_IN_MEMCPY:
       target = expand_builtin_memcpy (arglist);
       if (target)
@@ -2696,6 +2763,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
     case BUILT_IN_PUTS:
     case BUILT_IN_FPUTC:
     case BUILT_IN_FWRITE:
+    case BUILT_IN_STRCHR:
       break;
       
     case BUILT_IN_FPUTS:
index eda40d8762f44a1baad584a371cd5792959fa375..13e0f41839ec3c63cbbe56ff3ec6346ad853cf34 100644 (file)
@@ -39,6 +39,8 @@ DEF_BUILTIN(BUILT_IN_BCMP)
 DEF_BUILTIN(BUILT_IN_STRCPY)
 DEF_BUILTIN(BUILT_IN_STRCMP)
 DEF_BUILTIN(BUILT_IN_STRLEN)
+DEF_BUILTIN(BUILT_IN_STRSTR)
+DEF_BUILTIN(BUILT_IN_STRCHR)
 DEF_BUILTIN(BUILT_IN_FSQRT)
 DEF_BUILTIN(BUILT_IN_SIN)
 DEF_BUILTIN(BUILT_IN_COS)
index e9ce259901acdaa65e4b6f1be1f07f234ea6914c..03875fae59d58c70ab31578f36b7dd9fc766f97a 100644 (file)
@@ -4819,6 +4819,7 @@ c_common_nodes_and_builtins ()
   tree float_ftype_float, ldouble_ftype_ldouble;
   tree int_ftype_cptr_cptr_sizet;
   tree int_ftype_string_string, string_ftype_ptr_ptr;
+  tree string_ftype_string_int, string_ftype_string_string;
   tree long_ftype_long;
   tree longlong_ftype_longlong;
   /* Either char* or void*.  */
@@ -4933,6 +4934,22 @@ c_common_nodes_and_builtins ()
                                                 const_string_type_node,
                                                 endlink)));
 
+  /* Prototype for strstr, etc.  */
+  string_ftype_string_string
+    = build_function_type (string_type_node,
+                          tree_cons (NULL_TREE, const_string_type_node,
+                                     tree_cons (NULL_TREE,
+                                                const_string_type_node,
+                                                endlink)));
+
+  /* Prototype for strchr.  */
+  string_ftype_string_int
+    = build_function_type (string_type_node,
+                          tree_cons (NULL_TREE, const_string_type_node,
+                                     tree_cons (NULL_TREE,
+                                                integer_type_node,
+                                                endlink)));
+
   /* Prototype for strlen.  */
   strlen_ftype
     = build_function_type (traditional_len_type_node,
@@ -5154,6 +5171,11 @@ c_common_nodes_and_builtins ()
                    BUILT_IN_BCMP, BUILT_IN_NORMAL, "bcmp");
   builtin_function ("__builtin_strcmp", int_ftype_string_string,
                    BUILT_IN_STRCMP, BUILT_IN_NORMAL, "strcmp");
+  builtin_function ("__builtin_strstr", string_ftype_string_string,
+                   BUILT_IN_STRSTR, BUILT_IN_NORMAL, "strstr");
+  built_in_decls[BUILT_IN_STRCHR] =
+    builtin_function ("__builtin_strchr", string_ftype_string_int,
+                   BUILT_IN_STRCHR, BUILT_IN_NORMAL, "strchr");
   builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr,
                    BUILT_IN_STRCPY, BUILT_IN_NORMAL, "strcpy");
   builtin_function ("__builtin_strlen", strlen_ftype,
@@ -5222,6 +5244,8 @@ c_common_nodes_and_builtins ()
                        BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP,
                        BUILT_IN_NORMAL, NULL_PTR);
+      builtin_function ("strstr", string_ftype_string_string, BUILT_IN_STRSTR,
+                       BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY,
                        BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("strlen", strlen_ftype, BUILT_IN_STRLEN,