Commit b7f6588d by Jason Merrill Committed by Jason Merrill

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
parent f75778a8
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) Sun Feb 15 23:28:44 1998 Jeffrey A Law (law@cygnus.com)
* toplev.c (flag_schedule_reverse_before_reload): Delete variable. * toplev.c (flag_schedule_reverse_before_reload): Delete variable.
......
...@@ -5920,7 +5920,7 @@ fold (expr) ...@@ -5920,7 +5920,7 @@ fold (expr)
/* Pull arithmetic ops out of the CLEANUP_POINT_EXPR where /* Pull arithmetic ops out of the CLEANUP_POINT_EXPR where
appropriate. */ appropriate. */
case CLEANUP_POINT_EXPR: case CLEANUP_POINT_EXPR:
if (! TREE_SIDE_EFFECTS (arg0)) if (! has_cleanups (arg0))
return TREE_OPERAND (t, 0); return TREE_OPERAND (t, 0);
{ {
...@@ -5941,12 +5941,14 @@ fold (expr) ...@@ -5941,12 +5941,14 @@ fold (expr)
{ {
arg01 = TREE_OPERAND (arg0, 1); 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, return fold (build (code0, type, arg00,
fold (build1 (CLEANUP_POINT_EXPR, fold (build1 (CLEANUP_POINT_EXPR,
TREE_TYPE (arg01), arg01)))); TREE_TYPE (arg01), arg01))));
if (! TREE_SIDE_EFFECTS (arg01)) if (TREE_CONSTANT (arg01))
return fold (build (code0, type, return fold (build (code0, type,
fold (build1 (CLEANUP_POINT_EXPR, fold (build1 (CLEANUP_POINT_EXPR,
TREE_TYPE (arg00), arg00)), TREE_TYPE (arg00), arg00)),
......
...@@ -547,29 +547,10 @@ print_node (file, prefix, node, indent) ...@@ -547,29 +547,10 @@ print_node (file, prefix, node, indent)
return; return;
} }
first_rtl = len = tree_code_length[(int) TREE_CODE (node)]; len = tree_code_length[(int) TREE_CODE (node)];
/* These kinds of nodes contain rtx's, not trees, /* Some nodes contain rtx's, not trees,
after a certain point. Print the rtx's as rtx's. */ after a certain point. Print the rtx's as rtx's. */
switch (TREE_CODE (node)) first_rtl = first_rtl_op (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;
}
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
if (i >= first_rtl) if (i >= first_rtl)
......
...@@ -2387,6 +2387,31 @@ unsave_expr (expr) ...@@ -2387,6 +2387,31 @@ unsave_expr (expr)
return t; 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 /* Modify a tree in place so that all the evaluate only once things
are cleared out. Return the EXPR given. */ are cleared out. Return the EXPR given. */
...@@ -2402,12 +2427,11 @@ unsave_expr_now (expr) ...@@ -2402,12 +2427,11 @@ unsave_expr_now (expr)
return expr; return expr;
code = TREE_CODE (expr); code = TREE_CODE (expr);
first_rtl = tree_code_length [(int) code]; first_rtl = first_rtl_op (code);
switch (code) switch (code)
{ {
case SAVE_EXPR: case SAVE_EXPR:
SAVE_EXPR_RTL (expr) = 0; SAVE_EXPR_RTL (expr) = 0;
first_rtl = 2;
break; break;
case TARGET_EXPR: case TARGET_EXPR:
...@@ -2419,7 +2443,6 @@ unsave_expr_now (expr) ...@@ -2419,7 +2443,6 @@ unsave_expr_now (expr)
/* I don't yet know how to emit a sequence multiple times. */ /* I don't yet know how to emit a sequence multiple times. */
if (RTL_EXPR_SEQUENCE (expr) != 0) if (RTL_EXPR_SEQUENCE (expr) != 0)
abort (); abort ();
first_rtl = 0;
break; break;
case CALL_EXPR: case CALL_EXPR:
...@@ -2434,16 +2457,6 @@ unsave_expr_now (expr) ...@@ -2434,16 +2457,6 @@ unsave_expr_now (expr)
exp = TREE_CHAIN (exp); 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; break;
default: default:
...@@ -2561,6 +2574,64 @@ contains_placeholder_p (exp) ...@@ -2561,6 +2574,64 @@ contains_placeholder_p (exp)
return 0; 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, /* 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 return a tree with all occurrences of references to F in a
......
...@@ -1490,6 +1490,11 @@ extern int lvalue_or_else PROTO((tree, char *)); ...@@ -1490,6 +1490,11 @@ extern int lvalue_or_else PROTO((tree, char *));
extern tree save_expr PROTO((tree)); 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 /* unsave_expr (EXP) returns an expression equivalent to EXP but it
can be used multiple times and will evaluate EXP, in it's entirety can be used multiple times and will evaluate EXP, in it's entirety
each time. */ each time. */
...@@ -1509,6 +1514,11 @@ extern tree unsave_expr_now PROTO((tree)); ...@@ -1509,6 +1514,11 @@ extern tree unsave_expr_now PROTO((tree));
extern int contains_placeholder_p 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, /* 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 return a tree with all occurrences of references to F in a
PLACEHOLDER_EXPR replaced by R. Note that we assume here that EXP PLACEHOLDER_EXPR replaced by R. Note that we assume here that EXP
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment