This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] fix opt/10399, again
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 27 Feb 2004 14:23:32 -0800
- Subject: [tree-ssa] fix opt/10399, again
When 10399 was fixed, we removed the problematic code from
expand_builtin_str[n]cmp, but not simplify_builtin_str[n]cmp.
Sigh.
r~
* builtins.c (simplify_builtin_strcmp): Don't export. Remove
length parameters. Remove conversion to memcmp.
(simplify_builtin_strncmp): Likewise.
* expr.h: Don't declare them.
* tree-ssa-ccp.c (ccp_fold_builtin): Don't call them.
Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.152.2.51
diff -c -p -d -r1.152.2.51 builtins.c
*** builtins.c 16 Feb 2004 12:35:41 -0000 1.152.2.51
--- builtins.c 27 Feb 2004 22:18:09 -0000
*************** static tree fold_builtin_strncmp (tree);
*** 169,174 ****
--- 169,176 ----
static tree fold_builtin_signbit (tree);
static tree simplify_builtin_memcmp (tree);
+ static tree simplify_builtin_strcmp (tree);
+ static tree simplify_builtin_strncmp (tree);
static tree simplify_builtin_strpbrk (tree);
static tree simplify_builtin_strstr (tree);
static tree simplify_builtin_strchr (tree);
*************** simplify_builtin (tree exp, int ignore)
*** 7576,7585 ****
val = simplify_builtin_strncpy (arglist, NULL_TREE);
break;
case BUILT_IN_STRCMP:
! val = simplify_builtin_strcmp (arglist, NULL_TREE, NULL_TREE);
break;
case BUILT_IN_STRNCMP:
! val = simplify_builtin_strncmp (arglist, NULL_TREE, NULL_TREE);
break;
case BUILT_IN_STRPBRK:
val = simplify_builtin_strpbrk (arglist);
--- 7578,7587 ----
val = simplify_builtin_strncpy (arglist, NULL_TREE);
break;
case BUILT_IN_STRCMP:
! val = simplify_builtin_strcmp (arglist);
break;
case BUILT_IN_STRNCMP:
! val = simplify_builtin_strncmp (arglist);
break;
case BUILT_IN_STRPBRK:
val = simplify_builtin_strpbrk (arglist);
*************** simplify_builtin_memcmp (tree arglist)
*** 8067,8076 ****
COMPOUND_EXPR in the chain will contain the tree for the simplified
form of the builtin function call. */
! tree
! simplify_builtin_strcmp (tree arglist, tree len1, tree len2)
{
! tree arg1, arg2, fn;
const char *p1, *p2;
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
--- 8069,8078 ----
COMPOUND_EXPR in the chain will contain the tree for the simplified
form of the builtin function call. */
! static tree
! simplify_builtin_strcmp (tree arglist)
{
! tree arg1, arg2;
const char *p1, *p2;
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
*************** simplify_builtin_strcmp (tree arglist, t
*** 8079,8084 ****
--- 8081,8090 ----
arg1 = TREE_VALUE (arglist);
arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+ /* If both arguments are equal (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ return integer_zero_node;
+
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
*************** simplify_builtin_strcmp (tree arglist, t
*** 8107,8155 ****
return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
}
! if (!len1)
! len1 = c_strlen (arg1, 0);
! if (len1)
! len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
!
! if (!len2)
! len2 = c_strlen (arg2, 0);
! if (len2)
! len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
!
! /* If we don't have a constant length for the first, use the length
! of the second, if we know it. We don't require a constant for
! this case; some cost analysis could be done if both are available
! but neither is constant. For now, assume they're equally cheap
! unless one has side effects.
!
! If both strings have constant lengths, use the smaller. This
! could arise if optimization results in strcpy being called with
! two fixed strings, or if the code was machine-generated. We should
! add some code to the `memcmp' handler below to deal with such
! situations, someday. */
!
! if (!len1 || TREE_CODE (len1) != INTEGER_CST)
! {
! if (len2 && !TREE_SIDE_EFFECTS (len2))
! len1 = len2;
! else if (len1 == 0)
! return 0;
! }
! else if (len2 && TREE_CODE (len2) == INTEGER_CST
! && tree_int_cst_lt (len2, len1))
! len2 = len2;
!
! /* If both arguments have side effects, we cannot optimize. */
! if (TREE_SIDE_EFFECTS (len1))
! return 0;
!
! fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
! if (!fn)
! return 0;
!
! chainon (arglist, build_tree_list (NULL_TREE, len1));
! return build_function_call_expr (fn, arglist);
}
/* Simplify a call to the strncmp builtin.
--- 8113,8119 ----
return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
}
! return 0;
}
/* Simplify a call to the strncmp builtin.
*************** simplify_builtin_strcmp (tree arglist, t
*** 8169,8178 ****
COMPOUND_EXPR in the chain will contain the tree for the simplified
form of the builtin function call. */
! tree
! simplify_builtin_strncmp (tree arglist, tree len1, tree len2)
{
- tree fn, newarglist, len = 0;
tree arg1, arg2, arg3;
const char *p1, *p2;
--- 8133,8141 ----
COMPOUND_EXPR in the chain will contain the tree for the simplified
form of the builtin function call. */
! static tree
! simplify_builtin_strncmp (tree arglist)
{
tree arg1, arg2, arg3;
const char *p1, *p2;
*************** simplify_builtin_strncmp (tree arglist,
*** 8185,8191 ****
arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
/* If the len parameter is zero, return zero. */
! if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
{
/* Evaluate and ignore arg1 and arg2 in case they have
side-effects. */
--- 8148,8154 ----
arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
/* If the len parameter is zero, return zero. */
! if (integer_zerop (arg3))
{
/* Evaluate and ignore arg1 and arg2 in case they have
side-effects. */
*************** simplify_builtin_strncmp (tree arglist,
*** 8194,8199 ****
--- 8157,8169 ----
arg2, integer_zero_node));
}
+ /* If arg1 and arg2 are equal (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ {
+ /* Evaluate and ignore arg3 in case it has side-effects. */
+ return build (COMPOUND_EXPR, integer_type_node, arg3, integer_zero_node);
+ }
+
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
*************** simplify_builtin_strncmp (tree arglist,
*** 8226,8266 ****
return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
}
! /* If c_strlen can determine an expression for one of the string
! lengths, and it doesn't have side effects, then call
! expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3). */
!
! /* Perhaps one of the strings is really constant, if so prefer
! that constant length over the other string's length. */
! if (p1)
! len = len1 ? len1 : c_strlen (arg1, 0);
! else if (p2)
! len = len2 ? len2 : c_strlen (arg2, 0);
!
! /* If we still don't have a len, try either string arg as long
! as they don't have side effects. */
! if (!len && !TREE_SIDE_EFFECTS (arg1))
! len = c_strlen (arg1, 0);
! if (!len && !TREE_SIDE_EFFECTS (arg2))
! len = c_strlen (arg2, 0);
! /* If we still don't have a length, punt. */
! if (!len)
! return 0;
!
! fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
! if (!fn)
! return 0;
!
! /* Add one to the string length. */
! len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
!
! /* The actual new length parameter is MIN(len,arg3). */
! len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
!
! newarglist = build_tree_list (NULL_TREE, len);
! newarglist = tree_cons (NULL_TREE, arg2, newarglist);
! newarglist = tree_cons (NULL_TREE, arg1, newarglist);
! return build_function_call_expr (fn, newarglist);
}
/* Simplify a call to the strcat builtin.
--- 8196,8202 ----
return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
}
! return 0;
}
/* Simplify a call to the strcat builtin.
Index: expr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.h,v
retrieving revision 1.117.2.27
diff -c -p -d -r1.117.2.27 expr.h
*** expr.h 19 Feb 2004 09:05:25 -0000 1.117.2.27
--- expr.h 27 Feb 2004 22:18:09 -0000
*************** extern void record_alias_subset (HOST_WI
*** 372,379 ****
extern HOST_WIDE_INT new_alias_set (void);
extern int can_address_p (tree);
extern tree simplify_builtin_fputs (tree, int, int, tree);
- extern tree simplify_builtin_strcmp (tree, tree, tree);
- extern tree simplify_builtin_strncmp (tree, tree, tree);
extern tree simplify_builtin_strcpy (tree, tree);
extern tree simplify_builtin_strncpy (tree, tree);
--- 372,377 ----
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.143
diff -c -p -d -r1.1.2.143 tree-ssa-ccp.c
*** tree-ssa-ccp.c 25 Feb 2004 03:22:47 -0000 1.1.2.143
--- tree-ssa-ccp.c 27 Feb 2004 22:18:09 -0000
*************** ccp_fold_builtin (tree stmt, tree fn)
*** 2068,2076 ****
case BUILT_IN_STRNCPY:
strlen_arg = 2;
break;
- case BUILT_IN_STRCMP:
- case BUILT_IN_STRNCMP:
- strlen_arg = 3;
default:
return NULL_TREE;
}
--- 2068,2073 ----
*************** ccp_fold_builtin (tree stmt, tree fn)
*** 2102,2111 ****
return simplify_builtin_strcpy (arglist, strlen_val[1]);
case BUILT_IN_STRNCPY:
return simplify_builtin_strncpy (arglist, strlen_val[1]);
- case BUILT_IN_STRCMP:
- return simplify_builtin_strcmp (arglist, strlen_val[0], strlen_val[1]);
- case BUILT_IN_STRNCMP:
- return simplify_builtin_strncmp (arglist, strlen_val[0], strlen_val[1]);
case BUILT_IN_FPUTS:
return simplify_builtin_fputs (arglist,
TREE_CODE (stmt) != MODIFY_EXPR, 0,
--- 2099,2104 ----