From d558e4f8d338926f919121d8cc7d1a852f7ae952 Mon Sep 17 00:00:00 2001 From: rth <> Date: Sat, 18 Dec 2004 18:59:04 +0000 Subject: * tree-nested.c (save_tmp_var): New. (struct walk_stmt_info): Add is_lhs. (walk_stmts) : 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. --- gcc/tree-nested.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'gcc/tree-nested.c') diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index e5befa43a99..70b37772470 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -376,6 +376,23 @@ tsi_gimplify_val (struct nesting_info *info, tree exp, tree_stmt_iterator *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. */ static GTY(()) tree trampoline_type; @@ -517,6 +534,7 @@ struct walk_stmt_info tree_stmt_iterator tsi; struct nesting_info *info; bool val_only; + bool is_lhs; bool changed; }; @@ -567,12 +585,18 @@ walk_stmts (struct walk_stmt_info *wi, tree *tp) break; case MODIFY_EXPR: - /* The immediate arguments of a MODIFY_EXPR may use COMPONENT_REF. */ - wi->val_only = false; - walk_tree (&TREE_OPERAND (t, 0), wi->callback, wi, NULL); - wi->val_only = false; + /* A formal temporary lhs may use a COMPONENT_REF rhs. */ + wi->val_only = !is_gimple_formal_tmp_var (TREE_OPERAND (t, 0)); 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->is_lhs = false; break; default: @@ -789,8 +813,14 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) x = init_tmp_var (info, x, &wi->tsi); x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); } + 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; } @@ -802,6 +832,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) { *walk_subtrees = 1; wi->val_only = true; + wi->is_lhs = false; } break; @@ -818,8 +849,9 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) { bool save_val_only = wi->val_only; - wi->changed = false; wi->val_only = false; + wi->is_lhs = false; + wi->changed = false; walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL); wi->val_only = true; @@ -848,6 +880,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) anything that describes the references. Otherwise, we lose track of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */ wi->val_only = true; + wi->is_lhs = false; for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp) { if (TREE_CODE (t) == COMPONENT_REF) @@ -880,6 +913,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) { *walk_subtrees = 1; wi->val_only = true; + wi->is_lhs = false; } break; } @@ -922,8 +956,15 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) wi->changed = true; x = get_frame_field (info, info->context, field, &wi->tsi); + 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; } break; @@ -932,8 +973,9 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) { bool save_val_only = wi->val_only; - wi->changed = false; wi->val_only = false; + wi->is_lhs = false; + wi->changed = false; walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL); wi->val_only = save_val_only; @@ -963,6 +1005,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) anything that describes the references. Otherwise, we lose track of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */ wi->val_only = true; + wi->is_lhs = false; for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp) { if (TREE_CODE (t) == COMPONENT_REF) @@ -995,6 +1038,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) { *walk_subtrees = 1; wi->val_only = true; + wi->is_lhs = false; } break; } -- cgit v1.2.3