[ast-optimizer-branch] simplify builtins
Aldy Hernandez
aldyh@redhat.com
Mon Jun 24 20:58:00 GMT 2002
hi diego. hi guys.
[based on your original builtin simplify patch]
here's a patch to simplify builtins instead of bailing out.
there are a few vararg builtins that cannot be simplified because we require
the original arguments.
there are also a few string builtins where "const char *" arguments of
the form [STRING + INT] are better left unsimplified because otherwise
we put them in a variable, and the builtin misses an opportunity to
fold the entire thing.
this fixes all the regressions you pointed out.
ok?
2002-06-24 Aldy Hernandez <aldyh@quesejoda.com>
Diego Novillo <dnovillo@redhat.com>
* c-simplify.c (simplify_call_expr): Do not bail on all builtins.
* tree-simple.c (is_simplifiable_builtin): New.
(is_string_plus_int): New.
* tree-simple.h: New prototype for is_simplifiable_builtin.
Index: c-simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-simplify.c,v
retrieving revision 1.1.4.1
diff -c -p -r1.1.4.1 c-simplify.c
*** c-simplify.c 22 Jun 2002 04:39:22 -0000 1.1.4.1
--- c-simplify.c 25 Jun 2002 03:10:36 -0000
*************** simplify_call_expr (expr_p, pre_p, post_
*** 1501,1516 ****
tree *pre_p;
tree *post_p;
{
- tree id;
-
if (TREE_CODE (*expr_p) != CALL_EXPR)
abort ();
! /* Do not simplify calls to builtin functions as they may require
! specific tree nodes (e.g., __builtin_stdarg_start).
! FIXME: We should identify which builtins can be simplified safely. */
! id = get_callee_fndecl (*expr_p);
! if (id && DECL_BUILT_IN (id))
return;
simplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, is_simple_id,
--- 1501,1512 ----
tree *pre_p;
tree *post_p;
{
if (TREE_CODE (*expr_p) != CALL_EXPR)
abort ();
! /* Some builtins cannot be simplified because they require specific
! arguments (e.g., __builtin_stdarg_start). */
! if (!is_simplifiable_builtin (*expr_p))
return;
simplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, is_simple_id,
*************** simplify_call_expr (expr_p, pre_p, post_
*** 1518,1524 ****
simplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, is_simple_arglist,
fb_rvalue);
}
-
/* Simplify the TREE_LIST node pointed by EXPR_P.
--- 1514,1519 ----
Index: tree-simple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.c,v
retrieving revision 1.1.4.1
diff -c -p -r1.1.4.1 tree-simple.c
*** tree-simple.c 22 Jun 2002 04:39:44 -0000 1.1.4.1
--- tree-simple.c 25 Jun 2002 03:10:37 -0000
*************** Boston, MA 02111-1307, USA. */
*** 232,237 ****
--- 232,239 ----
| RETURN val ';'
| RETURN '(' val ')' ';' */
+ static int is_string_plus_int PARAMS((tree));
+
int
is_simple_stmt (t)
tree t;
*************** int
*** 670,690 ****
is_simple_call_expr (t)
tree t;
{
- tree decl;
-
if (t == NULL_TREE)
return 1;
if (TREE_CODE (t) != CALL_EXPR)
return 0;
! /* Consider that calls to builtin functions are in SIMPLE form already.
!
! FIXME: The simplifier will not simplify these calls because some
! builtins need specific arguments (e.g., __builtin_stdarg_start
! wants one of the function arguments as its last parameters). */
! decl = get_callee_fndecl (t);
! if (decl && DECL_BUILT_IN (decl))
return 1;
return (is_simple_id (TREE_OPERAND (t, 0))
--- 672,686 ----
is_simple_call_expr (t)
tree t;
{
if (t == NULL_TREE)
return 1;
if (TREE_CODE (t) != CALL_EXPR)
return 0;
! /* Some builtins cannot be simplified because the require specific
! arguments. */
! if (!is_simplifiable_builtin (t))
return 1;
return (is_simple_id (TREE_OPERAND (t, 0))
*************** is_simple_exprseq (t)
*** 1005,1008 ****
--- 1001,1085 ----
|| (TREE_CODE (t) == COMPOUND_EXPR
&& is_simple_expr (TREE_OPERAND (t, 0))
&& is_simple_exprseq (TREE_OPERAND (t, 1))));
+ }
+
+ /* Return nonzero if expr is of the [STRING_CST + INTEGER_CST] form. */
+
+ static int
+ is_string_plus_int (expr)
+ tree expr;
+ {
+ tree t1, t2;
+
+ STRIP_NOPS (expr);
+ if (TREE_CODE (expr) != PLUS_EXPR)
+ return 0;
+
+ t1 = TREE_OPERAND (expr, 0);
+ t2 = TREE_OPERAND (expr, 1);
+ STRIP_NOPS (t1);
+ STRIP_NOPS (t2);
+ return (TREE_CODE (t2) == INTEGER_CST
+ && TREE_CODE (t1) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (t1, 0)) == STRING_CST);
+ }
+
+ /* Return nonzero if FNDECL can be simplified. This is needed for
+ builtins like __builtin_stdarg_start expects its last parameter to be
+ one of the current function's arguments. */
+
+ int
+ is_simplifiable_builtin (expr)
+ tree expr;
+ {
+ enum built_in_function fcode;
+ tree decl, t1, t2;
+
+ decl = get_callee_fndecl (expr);
+
+ if (decl == NULL_TREE || !DECL_BUILT_IN (decl))
+ return 1;
+
+ fcode = DECL_FUNCTION_CODE (decl);
+
+ switch (fcode)
+ {
+ /* foo (const char *, const char *, ...). */
+ case BUILT_IN_STRSPN:
+ case BUILT_IN_STRSTR:
+ case BUILT_IN_STRCSPN:
+ t1 = TREE_VALUE (TREE_OPERAND (expr, 1));
+ t2 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (expr, 1)));
+
+ /* STRING+INT gets folded in the builtin. */
+ return !(is_string_plus_int (t1) || is_string_plus_int (t2));
+
+ /* foo (const char *, ...). */
+ case BUILT_IN_STRRCHR:
+ case BUILT_IN_STRCHR:
+ case BUILT_IN_INDEX:
+ case BUILT_IN_FPUTS:
+ t1 = TREE_VALUE (TREE_OPERAND (expr, 1));
+
+ /* STRING+INT gets folded in the builtin. */
+ return !is_string_plus_int (t1);
+
+ /* foo (..., const char *, ...). */
+ case BUILT_IN_STRCPY:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRCAT:
+ case BUILT_IN_STRNCAT:
+ t2 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (expr, 1)));
+
+ return !is_string_plus_int (t2);
+
+ case BUILT_IN_ARGS_INFO:
+ case BUILT_IN_STDARG_START:
+ case BUILT_IN_VA_END:
+ case BUILT_IN_VA_COPY:
+ case BUILT_IN_VARARGS_START:
+ return 0;
+
+ default:
+ return 1;
+ }
}
Index: tree-simple.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.h,v
retrieving revision 1.1.4.1
diff -c -p -r1.1.4.1 tree-simple.h
*** tree-simple.h 22 Jun 2002 04:39:45 -0000 1.1.4.1
--- tree-simple.h 25 Jun 2002 03:10:37 -0000
*************** int is_simple_exprseq P
*** 64,68 ****
--- 64,69 ----
int is_simple_constructor PARAMS ((tree));
int is_simple_constructor_elt PARAMS ((tree));
int is_simple_initializer PARAMS ((tree));
+ int is_simplifiable_builtin PARAMS ((tree));
#endif /* _TREE_SIMPLE_H */
More information about the Gcc-patches
mailing list