diff options
author | Jason Merrill <jason@yorick.cygnus.com> | 1998-02-16 04:52:31 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 1998-02-15 23:52:31 -0500 |
commit | b7f6588dd26feb66e936f4a3817d28c8ea929fae (patch) | |
tree | a79a0fce1411246619cb9375b2e5e885167e3226 /gcc | |
parent | f75778a8d6315df5f100475fa2cd1bb0423d8019 (diff) | |
download | gcc-b7f6588dd26feb66e936f4a3817d28c8ea929fae.zip gcc-b7f6588dd26feb66e936f4a3817d28c8ea929fae.tar.gz gcc-b7f6588dd26feb66e936f4a3817d28c8ea929fae.tar.bz2 |
tree.c (first_rtl_op): New fn.
* tree.c (first_rtl_op): New fn.
(unsave_expr_now): Use it.
* print-tree.c (print_node): Likewise.
* tree.c (has_cleanups): New fn.
* fold-const.c (fold, case CLEANUP_POINT_EXPR): Use it. Be more
conservative about pushing the cleanup point down.
* tree.h: Declare them.
From-SVN: r18023
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/fold-const.c | 8 | ||||
-rw-r--r-- | gcc/print-tree.c | 25 | ||||
-rw-r--r-- | gcc/tree.c | 97 | ||||
-rw-r--r-- | gcc/tree.h | 10 |
5 files changed, 112 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 472a5b3..ce452cb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +1998-02-16 Jason Merrill <jason@yorick.cygnus.com> + + * tree.c (first_rtl_op): New fn. + (unsave_expr_now): Use it. + * print-tree.c (print_node): Likewise. + * tree.c (has_cleanups): New fn. + * fold-const.c (fold, case CLEANUP_POINT_EXPR): Use it. Be more + conservative about pushing the cleanup point down. + * tree.h: Declare them. + Sun Feb 15 23:28:44 1998 Jeffrey A Law (law@cygnus.com) * toplev.c (flag_schedule_reverse_before_reload): Delete variable. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 4d021db..35d8beb 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5920,7 +5920,7 @@ fold (expr) /* Pull arithmetic ops out of the CLEANUP_POINT_EXPR where appropriate. */ case CLEANUP_POINT_EXPR: - if (! TREE_SIDE_EFFECTS (arg0)) + if (! has_cleanups (arg0)) return TREE_OPERAND (t, 0); { @@ -5941,12 +5941,14 @@ fold (expr) { arg01 = TREE_OPERAND (arg0, 1); - if (! TREE_SIDE_EFFECTS (arg00)) + if (TREE_CONSTANT (arg00) + || ((code0 == TRUTH_ANDIF_EXPR || code0 == TRUTH_ORIF_EXPR) + && ! has_cleanups (arg00))) return fold (build (code0, type, arg00, fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (arg01), arg01)))); - if (! TREE_SIDE_EFFECTS (arg01)) + if (TREE_CONSTANT (arg01)) return fold (build (code0, type, fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (arg00), arg00)), diff --git a/gcc/print-tree.c b/gcc/print-tree.c index f075f0b..5b81bc5 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -547,29 +547,10 @@ print_node (file, prefix, node, indent) return; } - first_rtl = len = tree_code_length[(int) TREE_CODE (node)]; - /* These kinds of nodes contain rtx's, not trees, + len = tree_code_length[(int) TREE_CODE (node)]; + /* Some nodes contain rtx's, not trees, after a certain point. Print the rtx's as rtx's. */ - switch (TREE_CODE (node)) - { - case SAVE_EXPR: - first_rtl = 2; - break; - case CALL_EXPR: - first_rtl = 2; - break; - case METHOD_CALL_EXPR: - first_rtl = 3; - break; - case WITH_CLEANUP_EXPR: - /* Should be defined to be 2. */ - first_rtl = 1; - break; - case RTL_EXPR: - first_rtl = 0; - default: - break; - } + first_rtl = first_rtl_op (TREE_CODE (node)); for (i = 0; i < len; i++) { if (i >= first_rtl) @@ -2387,6 +2387,31 @@ unsave_expr (expr) return t; } +/* Returns the index of the first non-tree operand for CODE, or the number + of operands if all are trees. */ + +int +first_rtl_op (code) + enum tree_code code; +{ + switch (code) + { + case SAVE_EXPR: + return 2; + case RTL_EXPR: + return 0; + case CALL_EXPR: + return 2; + case WITH_CLEANUP_EXPR: + /* Should be defined to be 2. */ + return 1; + case METHOD_CALL_EXPR: + return 3; + default: + return tree_code_length [(int) code]; + } +} + /* Modify a tree in place so that all the evaluate only once things are cleared out. Return the EXPR given. */ @@ -2402,12 +2427,11 @@ unsave_expr_now (expr) return expr; code = TREE_CODE (expr); - first_rtl = tree_code_length [(int) code]; + first_rtl = first_rtl_op (code); switch (code) { case SAVE_EXPR: SAVE_EXPR_RTL (expr) = 0; - first_rtl = 2; break; case TARGET_EXPR: @@ -2419,7 +2443,6 @@ unsave_expr_now (expr) /* I don't yet know how to emit a sequence multiple times. */ if (RTL_EXPR_SEQUENCE (expr) != 0) abort (); - first_rtl = 0; break; case CALL_EXPR: @@ -2434,16 +2457,6 @@ unsave_expr_now (expr) exp = TREE_CHAIN (exp); } } - first_rtl = 2; - break; - - case WITH_CLEANUP_EXPR: - /* Should be defined to be 2. */ - first_rtl = 1; - break; - - case METHOD_CALL_EXPR: - first_rtl = 3; break; default: @@ -2561,6 +2574,64 @@ contains_placeholder_p (exp) 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, cmp; + + 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; + + case CALL_EXPR: + for (exp = TREE_OPERAND (exp, 1); exp; exp = TREE_CHAIN (exp)) + { + cmp = has_cleanups (TREE_VALUE (exp)); + if (cmp) + return cmp; + } + 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 = first_rtl_op (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') + { + 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 @@ -1490,6 +1490,11 @@ extern int lvalue_or_else PROTO((tree, char *)); extern tree save_expr PROTO((tree)); +/* Returns the index of the first non-tree operand for CODE, or the number + of operands if all are trees. */ + +extern int first_rtl_op PROTO((enum tree_code)); + /* unsave_expr (EXP) returns an expression equivalent to EXP but it can be used multiple times and will evaluate EXP, in it's entirety each time. */ @@ -1509,6 +1514,11 @@ extern tree unsave_expr_now PROTO((tree)); 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 |