This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ jump optimization patch


This patch allows the do_jump code to optimize many more tests in C++.  As
a side effect, it eliminates the -Wuninitialized warning for this testcase:

void g(int a, const char *s)
{
  int c, count = 0;
  while (count++ < a && (c = *s++) != 0) {
    if (c == 8)
      break;
  }
}

1998-02-13  Jason Merrill  <jason@yorick.cygnus.com>

	* tree.c (has_cleanups): New fn.
	* fold-const.c (fold, case CLEANUP_POINT_EXPR): Use it.
	* tree.h: Declare it.

Index: fold-const.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/fold-const.c,v
retrieving revision 1.16
diff -c -p -r1.16 fold-const.c
*** fold-const.c	1998/02/01 11:47:57	1.16
--- fold-const.c	1998/02/13 23:51:09
*************** fold (expr) 
*** 5921,5927 ****
        /* Pull arithmetic ops out of the CLEANUP_POINT_EXPR where
           appropriate.  */
      case CLEANUP_POINT_EXPR:
!       if (! TREE_SIDE_EFFECTS (arg0))
  	return TREE_OPERAND (t, 0);
  
        {
--- 5921,5927 ----
        /* Pull arithmetic ops out of the CLEANUP_POINT_EXPR where
           appropriate.  */
      case CLEANUP_POINT_EXPR:
!       if (! has_cleanups (arg0))
  	return TREE_OPERAND (t, 0);
  
        {
*************** fold (expr) 
*** 5942,5953 ****
  	  {
  	    arg01 = TREE_OPERAND (arg0, 1);
  
! 	    if (! TREE_SIDE_EFFECTS (arg00))
  	      return fold (build (code0, type, arg00,
  				  fold (build1 (CLEANUP_POINT_EXPR,
  						TREE_TYPE (arg01), arg01))));
  
! 	    if (! TREE_SIDE_EFFECTS (arg01))
  	      return fold (build (code0, type,
  				  fold (build1 (CLEANUP_POINT_EXPR,
  						TREE_TYPE (arg00), arg00)),
--- 5942,5953 ----
  	  {
  	    arg01 = TREE_OPERAND (arg0, 1);
  
! 	    if (! has_cleanups (arg00))
  	      return fold (build (code0, type, arg00,
  				  fold (build1 (CLEANUP_POINT_EXPR,
  						TREE_TYPE (arg01), arg01))));
  
! 	    if (! has_cleanups (arg01))
  	      return fold (build (code0, type,
  				  fold (build1 (CLEANUP_POINT_EXPR,
  						TREE_TYPE (arg00), arg00)),
Index: tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.c,v
retrieving revision 1.12
diff -c -p -r1.12 tree.c
*** tree.c	1998/01/27 22:11:51	1.12
--- tree.c	1998/02/13 23:51:09
*************** contains_placeholder_p (exp)
*** 2561,2566 ****
--- 2561,2615 ----
        return 0;
      }
  }
+ 
+ /* Return 1 if EXP contains any expressions that produce cleanups for an
+    outer scope to deal with.  Used by fold.  */
+ 
+ int
+ has_cleanups (exp)
+      tree exp;
+ {
+   int i, nops;
+ 
+   if (! TREE_SIDE_EFFECTS (exp))
+     return 0;
+ 
+   switch (TREE_CODE (exp))
+     {
+     case TARGET_EXPR:
+     case WITH_CLEANUP_EXPR:
+       return 1;
+ 
+     case CLEANUP_POINT_EXPR:
+       return 0;
+ 
+     default:
+       break;
+     }
+ 
+   /* This general rule works for most tree codes.  All exceptions should be
+      handled above.  If this is a language-specific tree code, we can't
+      trust what might be in the operand, so say we don't know
+      the situation.  */
+   if ((int) TREE_CODE (exp) >= (int) LAST_AND_UNUSED_TREE_CODE)
+     return -1;
+ 
+   nops = tree_code_length[(int) TREE_CODE (exp)];
+   for (i = 0; i < nops; i++)
+     if (TREE_OPERAND (exp, i) != 0)
+       {
+ 	int type = TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, i)));
+ 	if (type == 'e' || type == '<' || type == '1' || type == '2'
+ 	    || type == 'r' || type == 's')
+ 	  {
+ 	    int cmp = has_cleanups (TREE_OPERAND (exp, i));
+ 	    if (cmp)
+ 	      return cmp;
+ 	  }
+       }
+ 
+   return 0;
+ }
  
  /* Given a tree EXP, a FIELD_DECL F, and a replacement value R,
     return a tree with all occurrences of references to F in a
Index: tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.h,v
retrieving revision 1.14
diff -c -p -r1.14 tree.h
*** tree.h	1998/02/01 11:47:59	1.14
--- tree.h	1998/02/13 23:51:09
*************** tree.h		PROTO((tree
*** 1509,1514 ****
--- 1509,1519 ----
  
  extern int contains_placeholder_p	PROTO((tree));
  
+ /* Return 1 if EXP contains any expressions that produce cleanups for an
+    outer scope to deal with.  Used by fold.  */
+ 
+ extern int has_cleanups			PROTO((tree));
+ 
  /* Given a tree EXP, a FIELD_DECL F, and a replacement value R,
     return a tree with all occurrences of references to F in a
     PLACEHOLDER_EXPR replaced by R.   Note that we assume here that EXP


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]