This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
C++ jump optimization patch
- To: law at cygnus dot com, egcs at cygnus dot com
- Subject: C++ jump optimization patch
- From: Jason Merrill <jason at cygnus dot com>
- Date: Fri, 13 Feb 1998 15:57:11 -0800
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