This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [tree-ssa-branch] simplify builtins
> > + 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;
> > +
> Explain why these can't be simplified.
because i was on crack when i wrote the patch? ;-)
the following are needed though:
+ case BUILT_IN_STDARG_START:
+ case BUILT_IN_VARARGS_START:
+ case BUILT_IN_VA_COPY:
BUILT_IN_STDARG_START and BUILT_IN_VARARGS_START cannot be simplified
because their last argument needs an actual argument of the function.
(btw, internally they both call the same builtin).
BUILT_IN_VA_COPY is needed because it makes a copy of the va_list.
it needs the actual thing (for the source operand), not a copy. else
we could just implement it with:
#define va_copy(a,b) (a) = (b)
;-)
> The patch seems otherwise OK. Please commit after bootstrapping and
> testing.
i need another nod because i changed 2 things.
1. is_string_plus_int() was just replicating string_constant() which is
what the expand_builtins were using. so now i just call that.
less code, cleaner, and catches more corner cases :).
2. is_simple_compound_lval() was bailing out on INDIRECT_REFs, so it
never got a chance to call is_simple_min_lval(). this was causing
a vararg regression.
bootstrapped and tested on x86-linux.
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.
(is_simple_call_expr): Same.
* tree-simple.c (is_simplifiable_builtin): New.
(is_simple_compound_lval): Do not bail on INDIRECT_REF.
* 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 27 Jun 2002 19:11:22 -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 27 Jun 2002 19:11:23 -0000
*************** 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))
--- 670,684 ----
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_compound_lval (t)
*** 764,770 ****
if (TREE_CODE (t) == NON_LVALUE_EXPR)
t = TREE_OPERAND (t, 0);
! if (TREE_CODE (t) != ARRAY_REF && TREE_CODE (t) != COMPONENT_REF)
return 0;
for (; TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF;
--- 758,766 ----
if (TREE_CODE (t) == NON_LVALUE_EXPR)
t = TREE_OPERAND (t, 0);
! if (TREE_CODE (t) != ARRAY_REF
! && TREE_CODE (t) != COMPONENT_REF
! && TREE_CODE (t) != INDIRECT_REF)
return 0;
for (; TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF;
*************** is_simple_exprseq (t)
*** 1005,1008 ****
--- 1001,1067 ----
|| (TREE_CODE (t) == COMPOUND_EXPR
&& is_simple_expr (TREE_OPERAND (t, 0))
&& is_simple_exprseq (TREE_OPERAND (t, 1))));
+ }
+
+ /* 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, t3;
+
+ decl = get_callee_fndecl (expr);
+
+ if (decl == NULL_TREE || !DECL_BUILT_IN (decl))
+ return 1;
+
+ fcode = DECL_FUNCTION_CODE (decl);
+
+ switch (fcode)
+ {
+ /* Many of the string builtins fold certain string patterns into
+ constants. Make sure we don't simplify something which will
+ be folded by the builtin later. */
+
+ /* foo (const char *, const char *, ...). */
+ case BUILT_IN_STRNCMP:
+ 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)));
+
+ return !(string_constant (t1, &t3) || string_constant (t2, &t3));
+
+ /* foo (const char *, ...). */
+ case BUILT_IN_STRLEN:
+ case BUILT_IN_STRRCHR:
+ case BUILT_IN_STRCHR:
+ case BUILT_IN_INDEX:
+ case BUILT_IN_FPUTS:
+ t1 = TREE_VALUE (TREE_OPERAND (expr, 1));
+
+ return !string_constant (t1, &t3);
+
+ /* 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 !string_constant (t2, &t3);
+
+ case BUILT_IN_STDARG_START:
+ case BUILT_IN_VARARGS_START:
+ case BUILT_IN_VA_COPY:
+ 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 27 Jun 2002 19:11:23 -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 */