Commit c529c27e by Richard Henderson Committed by Richard Henderson

tree-nested.c (save_tmp_var): New.

        * tree-nested.c (save_tmp_var): New.
        (struct walk_stmt_info): Add is_lhs.
        (walk_stmts) <MODIFY_EXPR>: Be more accurate with setting of
        val_only; set is_lhs.
        (convert_nonlocal_reference): Use save_tmp_var when is_lhs;
        clear is_lhs when appropriate.
        (convert_local_reference): Likewise.

From-SVN: r92357
parent 8cd0dbef
2004-12-18 Richard Henderson <rth@redhat.com>
* tree-nested.c (save_tmp_var): New.
(struct walk_stmt_info): Add is_lhs.
(walk_stmts) <MODIFY_EXPR>: Be more accurate with setting of
val_only; set is_lhs.
(convert_nonlocal_reference): Use save_tmp_var when is_lhs;
clear is_lhs when appropriate.
(convert_local_reference): Likewise.
2004-12-18 Richard Earnshaw <rearnsha@arm.com> 2004-12-18 Richard Earnshaw <rearnsha@arm.com>
* arm/ieee754-sf.S (floatdisf): Fix label definition in FPA * arm/ieee754-sf.S (floatdisf): Fix label definition in FPA
......
...@@ -376,6 +376,23 @@ tsi_gimplify_val (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi) ...@@ -376,6 +376,23 @@ tsi_gimplify_val (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
return init_tmp_var (info, exp, tsi); return init_tmp_var (info, exp, tsi);
} }
/* Similarly, but copy from the temporary and insert the statement
after the iterator. */
static tree
save_tmp_var (struct nesting_info *info, tree exp,
tree_stmt_iterator *tsi)
{
tree t, stmt;
t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
stmt = build (MODIFY_EXPR, TREE_TYPE (t), exp, t);
SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
tsi_link_after (tsi, stmt, TSI_SAME_STMT);
return t;
}
/* Build or return the type used to represent a nested function trampoline. */ /* Build or return the type used to represent a nested function trampoline. */
static GTY(()) tree trampoline_type; static GTY(()) tree trampoline_type;
...@@ -517,6 +534,7 @@ struct walk_stmt_info ...@@ -517,6 +534,7 @@ struct walk_stmt_info
tree_stmt_iterator tsi; tree_stmt_iterator tsi;
struct nesting_info *info; struct nesting_info *info;
bool val_only; bool val_only;
bool is_lhs;
bool changed; bool changed;
}; };
...@@ -567,12 +585,18 @@ walk_stmts (struct walk_stmt_info *wi, tree *tp) ...@@ -567,12 +585,18 @@ walk_stmts (struct walk_stmt_info *wi, tree *tp)
break; break;
case MODIFY_EXPR: case MODIFY_EXPR:
/* The immediate arguments of a MODIFY_EXPR may use COMPONENT_REF. */ /* A formal temporary lhs may use a COMPONENT_REF rhs. */
wi->val_only = false; wi->val_only = !is_gimple_formal_tmp_var (TREE_OPERAND (t, 0));
walk_tree (&TREE_OPERAND (t, 0), wi->callback, wi, NULL);
wi->val_only = false;
walk_tree (&TREE_OPERAND (t, 1), wi->callback, wi, NULL); walk_tree (&TREE_OPERAND (t, 1), wi->callback, wi, NULL);
/* If the rhs is appropriate for a memory, we may use a
COMPONENT_REF on the lhs. */
wi->val_only = !is_gimple_mem_rhs (TREE_OPERAND (t, 1));
wi->is_lhs = true;
walk_tree (&TREE_OPERAND (t, 0), wi->callback, wi, NULL);
wi->val_only = true; wi->val_only = true;
wi->is_lhs = false;
break; break;
default: default:
...@@ -789,8 +813,14 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) ...@@ -789,8 +813,14 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
x = init_tmp_var (info, x, &wi->tsi); x = init_tmp_var (info, x, &wi->tsi);
x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
} }
if (wi->val_only) if (wi->val_only)
x = init_tmp_var (info, x, &wi->tsi); {
if (wi->is_lhs)
x = save_tmp_var (info, x, &wi->tsi);
else
x = init_tmp_var (info, x, &wi->tsi);
}
*tp = x; *tp = x;
} }
...@@ -802,6 +832,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) ...@@ -802,6 +832,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
{ {
*walk_subtrees = 1; *walk_subtrees = 1;
wi->val_only = true; wi->val_only = true;
wi->is_lhs = false;
} }
break; break;
...@@ -818,8 +849,9 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) ...@@ -818,8 +849,9 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
{ {
bool save_val_only = wi->val_only; bool save_val_only = wi->val_only;
wi->changed = false;
wi->val_only = false; wi->val_only = false;
wi->is_lhs = false;
wi->changed = false;
walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL); walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
wi->val_only = true; wi->val_only = true;
...@@ -848,6 +880,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) ...@@ -848,6 +880,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
anything that describes the references. Otherwise, we lose track anything that describes the references. Otherwise, we lose track
of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */ of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */
wi->val_only = true; wi->val_only = true;
wi->is_lhs = false;
for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp) for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp)
{ {
if (TREE_CODE (t) == COMPONENT_REF) if (TREE_CODE (t) == COMPONENT_REF)
...@@ -880,6 +913,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) ...@@ -880,6 +913,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
{ {
*walk_subtrees = 1; *walk_subtrees = 1;
wi->val_only = true; wi->val_only = true;
wi->is_lhs = false;
} }
break; break;
} }
...@@ -922,8 +956,15 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) ...@@ -922,8 +956,15 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
wi->changed = true; wi->changed = true;
x = get_frame_field (info, info->context, field, &wi->tsi); x = get_frame_field (info, info->context, field, &wi->tsi);
if (wi->val_only) if (wi->val_only)
x = init_tmp_var (info, x, &wi->tsi); {
if (wi->is_lhs)
x = save_tmp_var (info, x, &wi->tsi);
else
x = init_tmp_var (info, x, &wi->tsi);
}
*tp = x; *tp = x;
} }
break; break;
...@@ -932,8 +973,9 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) ...@@ -932,8 +973,9 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
{ {
bool save_val_only = wi->val_only; bool save_val_only = wi->val_only;
wi->changed = false;
wi->val_only = false; wi->val_only = false;
wi->is_lhs = false;
wi->changed = false;
walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL); walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
wi->val_only = save_val_only; wi->val_only = save_val_only;
...@@ -963,6 +1005,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) ...@@ -963,6 +1005,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
anything that describes the references. Otherwise, we lose track anything that describes the references. Otherwise, we lose track
of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */ of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */
wi->val_only = true; wi->val_only = true;
wi->is_lhs = false;
for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp) for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp)
{ {
if (TREE_CODE (t) == COMPONENT_REF) if (TREE_CODE (t) == COMPONENT_REF)
...@@ -995,6 +1038,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) ...@@ -995,6 +1038,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
{ {
*walk_subtrees = 1; *walk_subtrees = 1;
wi->val_only = true; wi->val_only = true;
wi->is_lhs = false;
} }
break; break;
} }
......
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