[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