expr.c (expand_expr, [...]): Move from the C++ frontend to the backend where it belongs.
* expr.c (expand_expr, cond UNSAVE_EXPR): Move from the C++ frontend to the backend where it belongs. * tree.c (unsave_expr): Ditto. (unsave_expr_now): Ditto. * tree.def (UNSAVE_EXPR): Ditto. * cp-tree.h (unsave_expr): Ditto. (unsave_expr_now): Ditto. From-SVN: r12016
This commit is contained in:
parent
679163cf4d
commit
8a5d3064fb
@ -35,15 +35,6 @@ DEFTREECODE (CP_OFFSET_REF, "cp_offset_ref", "r", 2)
|
||||
DEFTREECODE (DELETE_EXPR, "dl_expr", "e", 2)
|
||||
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", "e", 2)
|
||||
|
||||
/* For a UNSAVE_EXPR, operand 0 is the value to unsave. By unsave, we
|
||||
mean that all _EXPRs such as TARGET_EXPRs, SAVE_EXPRs,
|
||||
CALL_EXPRs and RTL_EXPRs, that are protected
|
||||
from being evaluated more than once should be reset so that a new
|
||||
expand_expr call of this expr will cause those to be re-evaluated.
|
||||
This is useful when we want to reuse a tree in different places,
|
||||
but where we must re-expand. */
|
||||
DEFTREECODE (UNSAVE_EXPR, "unsave_expr", "e", 1)
|
||||
|
||||
/* Value is reference to particular overloaded class method.
|
||||
Operand 0 is the class name (an IDENTIFIER_NODE);
|
||||
operand 1 is the field (also an IDENTIFIER_NODE).
|
||||
|
@ -2151,7 +2151,6 @@ extern tree start_anon_func PROTO((void));
|
||||
/* skip cplus_expand_expr */
|
||||
extern void init_cplus_expand PROTO((void));
|
||||
extern void fixup_result_decl PROTO((tree, struct rtx_def *));
|
||||
extern tree unsave_expr_now PROTO((tree));
|
||||
|
||||
/* in repo.c */
|
||||
extern void init_repo PROTO((char*));
|
||||
@ -2404,8 +2403,6 @@ extern void print_lang_statistics PROTO((void));
|
||||
extern tree array_type_nelts_total PROTO((tree));
|
||||
extern tree array_type_nelts_top PROTO((tree));
|
||||
extern tree break_out_target_exprs PROTO((tree));
|
||||
extern tree build_unsave_expr PROTO((tree));
|
||||
extern tree unsave_expr PROTO((tree));
|
||||
extern int cp_expand_decl_cleanup PROTO((tree, tree));
|
||||
extern tree get_type_decl PROTO((tree));
|
||||
extern tree vec_binfo_member PROTO((tree, tree));
|
||||
|
@ -226,14 +226,6 @@ cplus_expand_expr (exp, target, tmode, modifier)
|
||||
expand_throw (TREE_OPERAND (exp, 0));
|
||||
return NULL;
|
||||
|
||||
case UNSAVE_EXPR:
|
||||
{
|
||||
rtx temp;
|
||||
temp = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
|
||||
TREE_OPERAND (exp, 0) = unsave_expr_now (TREE_OPERAND (exp, 0));
|
||||
return temp;
|
||||
}
|
||||
|
||||
case VEC_INIT_EXPR:
|
||||
return expand_expr
|
||||
(expand_vec_init
|
||||
|
@ -1753,91 +1753,6 @@ break_out_target_exprs (t)
|
||||
return mapcar (t, bot_manip);
|
||||
}
|
||||
|
||||
/* Arrange for an expression to be expanded multiple independent
|
||||
times. This is useful for cleanup actions, as the backend can
|
||||
expand them multiple times in different places. */
|
||||
tree
|
||||
unsave_expr (expr)
|
||||
tree expr;
|
||||
{
|
||||
tree t;
|
||||
|
||||
/* If this is already protected, no sense in protecting it again. */
|
||||
if (TREE_CODE (expr) == UNSAVE_EXPR)
|
||||
return expr;
|
||||
|
||||
t = build1 (UNSAVE_EXPR, TREE_TYPE (expr), expr);
|
||||
TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (expr);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Modify a tree in place so that all the evaluate only once things
|
||||
are cleared out. Return the EXPR given. */
|
||||
tree
|
||||
unsave_expr_now (expr)
|
||||
tree expr;
|
||||
{
|
||||
enum tree_code code;
|
||||
register int i;
|
||||
|
||||
if (expr == NULL_TREE)
|
||||
return expr;
|
||||
|
||||
code = TREE_CODE (expr);
|
||||
switch (code)
|
||||
{
|
||||
case SAVE_EXPR:
|
||||
SAVE_EXPR_RTL (expr) = NULL_RTX;
|
||||
break;
|
||||
|
||||
case TARGET_EXPR:
|
||||
sorry ("TARGET_EXPR reused inside UNSAVE_EXPR");
|
||||
break;
|
||||
|
||||
case RTL_EXPR:
|
||||
warning ("RTL_EXPR reused inside UNSAVE_EXPR");
|
||||
RTL_EXPR_SEQUENCE (expr) = NULL_RTX;
|
||||
break;
|
||||
|
||||
case CALL_EXPR:
|
||||
CALL_EXPR_RTL (expr) = NULL_RTX;
|
||||
if (TREE_OPERAND (expr, 1)
|
||||
&& TREE_CODE (TREE_OPERAND (expr, 1)) == TREE_LIST)
|
||||
{
|
||||
tree exp = TREE_OPERAND (expr, 1);
|
||||
while (exp)
|
||||
{
|
||||
unsave_expr_now (TREE_VALUE (exp));
|
||||
exp = TREE_CHAIN (exp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (TREE_CODE_CLASS (code))
|
||||
{
|
||||
case 'c': /* a constant */
|
||||
case 't': /* a type node */
|
||||
case 'x': /* something random, like an identifier or an ERROR_MARK. */
|
||||
case 'd': /* A decl node */
|
||||
case 'b': /* A block node */
|
||||
return expr;
|
||||
|
||||
case 'e': /* an expression */
|
||||
case 'r': /* a reference */
|
||||
case 's': /* an expression with side effects */
|
||||
case '<': /* a comparison expression */
|
||||
case '2': /* a binary arithmetic expression */
|
||||
case '1': /* a unary arithmetic expression */
|
||||
for (i = tree_code_length[(int) code] - 1; i >= 0; i--)
|
||||
unsave_expr_now (TREE_OPERAND (expr, i));
|
||||
return expr;
|
||||
|
||||
default:
|
||||
my_friendly_abort (999);
|
||||
}
|
||||
}
|
||||
|
||||
/* Since cleanup may have SAVE_EXPRs in it, we protect it with an
|
||||
UNSAVE_EXPR as the backend cannot yet handle SAVE_EXPRs in cleanups
|
||||
by itself. */
|
||||
|
Loading…
Reference in New Issue
Block a user