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)
* toplev.c (flag_schedule_reverse_before_reload): Delete variable.
......
......@@ -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)),
......
......@@ -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
......
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