From 78e7629e9f2b78c8ade485fb2e209427d2696300 Mon Sep 17 00:00:00 2001 From: "Kaveh R. Ghazi" Date: Wed, 1 Nov 2000 03:22:21 +0000 Subject: [PATCH] builtins.c (expand_builtin_strstr): New function. * 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 | 10 +++++++ gcc/builtins.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/builtins.def | 2 ++ gcc/c-common.c | 24 +++++++++++++++++ 4 files changed, 104 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 750c1c2a2ba..c89515b5109 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2000-10-31 Kaveh R. Ghazi + + * 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 * config/i386/i386.c (fcmov_comparison_operator): Check for diff --git a/gcc/builtins.c b/gcc/builtins.c index 3304b68a46a..abb67476cd6 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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: diff --git a/gcc/builtins.def b/gcc/builtins.def index eda40d8762f..13e0f41839e 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -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) diff --git a/gcc/c-common.c b/gcc/c-common.c index e9ce259901a..03875fae59d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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, -- 2.30.2