From 8b0b334af3439179947522206b2478a28b908e61 Mon Sep 17 00:00:00 2001 From: Qing Zhao Date: Thu, 31 May 2018 20:01:42 +0000 Subject: 2nd Patch for PR78009 Patch for PR83026 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78809 Inline strcmp with small constant strings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83026 missing strlen optimization for strcmp of unequal strings The design doc for PR78809 is at: https://www.mail-archive.com/gcc@gcc.gnu.org/msg83822.html this patch is for the second part of change of PR78809 and PR83026: B. for strncmp (s1, s2, n) (!)= 0 or strcmp (s1, s2) (!)= 0 B.1. (PR83026) When the lengths of both arguments are constant and it's a strcmp: * if the lengths are NOT equal, we can safely fold the call to a non-zero value. * otherwise, do nothing now. B.2. (PR78809) When the length of one argument is constant, try to replace the call with a __builtin_str(n)cmp_eq call where possible, i.e: strncmp (s, STR, C) (!)= 0 in which, s is a pointer to a string, STR is a string with constant length, C is a constant. if (C <= strlen(STR) && sizeof_array(s) > C) { replace this call with __builtin_strncmp_eq (s, STR, C) (!)= 0 } if (C > strlen(STR) { it can be safely treated as a call to strcmp (s, STR) (!)= 0 can handled by the following strcmp. } strcmp (s, STR) (!)= 0 in which, s is a pointer to a string, STR is a string with constant length. if (sizeof_array(s) > strlen(STR)) { replace this call with __builtin_strcmp_eq (s, STR, strlen(STR)+1) (!)= 0 } later when expanding the new __builtin_str(n)cmp_eq calls, first expand them as __builtin_memcmp_eq, if the expansion does not succeed, change them back to call to __builtin_str(n)cmp. adding test case strcmpopt_2.c and strcmpopt_4.c into gcc.dg for part B of PR78809 adding test case strcmpopt_3.c into gcc.dg for PR83026 From-SVN: r261039 --- gcc/builtins.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'gcc/builtins.c') diff --git a/gcc/builtins.c b/gcc/builtins.c index 9741939..c96ac38 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -7139,12 +7139,45 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, return target; break; + /* Expand it as BUILT_IN_MEMCMP_EQ first. If not successful, change it + back to a BUILT_IN_STRCMP. Remember to delete the 3rd paramater + when changing it to a strcmp call. */ + case BUILT_IN_STRCMP_EQ: + target = expand_builtin_memcmp (exp, target, true); + if (target) + return target; + + /* Change this call back to a BUILT_IN_STRCMP. */ + TREE_OPERAND (exp, 1) + = build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_STRCMP)); + + /* Delete the last parameter. */ + unsigned int i; + vec *arg_vec; + vec_alloc (arg_vec, 2); + for (i = 0; i < 2; i++) + arg_vec->quick_push (CALL_EXPR_ARG (exp, i)); + exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), arg_vec); + /* FALLTHROUGH */ + case BUILT_IN_STRCMP: target = expand_builtin_strcmp (exp, target); if (target) return target; break; + /* Expand it as BUILT_IN_MEMCMP_EQ first. If not successful, change it + back to a BUILT_IN_STRNCMP. */ + case BUILT_IN_STRNCMP_EQ: + target = expand_builtin_memcmp (exp, target, true); + if (target) + return target; + + /* Change it back to a BUILT_IN_STRNCMP. */ + TREE_OPERAND (exp, 1) + = build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_STRNCMP)); + /* FALLTHROUGH */ + case BUILT_IN_STRNCMP: target = expand_builtin_strncmp (exp, target, mode); if (target) -- cgit v1.1