From bfeebecf52cc0591c439d1988ce52b78c34c2072 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 6 Jul 2004 16:02:22 -0700 Subject: [PATCH] tree-sra.c (struct sra_walk_fns): Revert 2004-07-05 change. * tree-sra.c (struct sra_walk_fns): Revert 2004-07-05 change. (sra_walk_modify_expr, scan_init): Likewise. (generate_element_zero): Check visited before scanning children. (generate_element_init): Set visited on error. (scalarize_init): Handle generate_element_init failure similar to use_block_copy. From-SVN: r84177 --- gcc/ChangeLog | 9 +++++++ gcc/tree-sra.c | 69 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 68ae8edabf6..6c8ed693719 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2004-07-06 Richard Henderson + + * tree-sra.c (struct sra_walk_fns): Revert 2004-07-05 change. + (sra_walk_modify_expr, scan_init): Likewise. + (generate_element_zero): Check visited before scanning children. + (generate_element_init): Set visited on error. + (scalarize_init): Handle generate_element_init failure similar + to use_block_copy. + 2004-07-06 Joseph S. Myers * toplev.h (NO_FRONT_END_DIAG, ATTRIBUTE_GCC_FE_DIAG): Define. diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 59205401324..2e2e85a812a 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -569,9 +569,8 @@ struct sra_walk_fns block_stmt_iterator *bsi); /* Invoked when ELT is initialized from a constant. VALUE may be NULL, - in which case it should be treated as an empty CONSTRUCTOR. Return - false if we found a case we couldn't handle. */ - bool (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi); + in which case it should be treated as an empty CONSTRUCTOR. */ + void (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi); /* Invoked when we have a copy between one scalarizable reference ELT and one non-scalarizable reference OTHER. IS_OUTPUT is true if ELT @@ -770,21 +769,18 @@ sra_walk_modify_expr (tree expr, block_stmt_iterator *bsi, { /* If this is an assignment from a constant, or constructor, then we have access to all of the elements individually. Invoke INIT. */ - if ((TREE_CODE (rhs) == COMPLEX_EXPR - || TREE_CODE (rhs) == COMPLEX_CST - || TREE_CODE (rhs) == CONSTRUCTOR) - && fns->init (lhs_elt, rhs, bsi)) - ; + if (TREE_CODE (rhs) == COMPLEX_EXPR + || TREE_CODE (rhs) == COMPLEX_CST + || TREE_CODE (rhs) == CONSTRUCTOR) + fns->init (lhs_elt, rhs, bsi); /* If this is an assignment from read-only memory, treat this as if we'd been passed the constructor directly. Invoke INIT. */ else if (TREE_CODE (rhs) == VAR_DECL && TREE_STATIC (rhs) && TREE_READONLY (rhs) - && targetm.binds_local_p (rhs) - && DECL_INITIAL (rhs) - && fns->init (lhs_elt, DECL_INITIAL (rhs), bsi)) - ; + && targetm.binds_local_p (rhs)) + fns->init (lhs_elt, DECL_INITIAL (rhs), bsi); /* If this is a copy from a non-scalarizable lvalue, invoke LDST. The lvalue requirement prevents us from trying to directly scalarize @@ -934,12 +930,11 @@ scan_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt, rhs_elt->n_copies += 1; } -static bool +static void scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED, block_stmt_iterator *bsi ATTRIBUTE_UNUSED) { lhs_elt->n_copies += 1; - return true; } static void @@ -1490,12 +1485,16 @@ generate_element_zero (struct sra_elt *elt, tree *list_p) { struct sra_elt *c; + if (elt->visited) + { + elt->visited = false; + return; + } + for (c = elt->children; c ; c = c->sibling) generate_element_zero (c, list_p); - if (elt->visited) - elt->visited = false; - else if (elt->replacement) + if (elt->replacement) { tree t; @@ -1567,6 +1566,7 @@ generate_element_init (struct sra_elt *elt, tree init, tree *list_p) break; default: + elt->visited = true; result = false; } @@ -1760,9 +1760,9 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt, /* Scalarize an INIT. To recap, this is an assignment to a scalarizable reference from some form of constructor: CONSTRUCTOR, COMPLEX_CST or COMPLEX_EXPR. If RHS is NULL, it should be treated as an empty - CONSTRUCTOR. Return false if we didn't handle this case. */ + CONSTRUCTOR. */ -static bool +static void scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi) { bool result = true; @@ -1776,28 +1776,41 @@ scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi) a zero value. Initialize the rest of the instantiated elements. */ generate_element_zero (lhs_elt, &list); - /* If we didn't generate anything or couldn't handle this case return. - Say which it was. */ - if (!result || list == NULL) - return result; + if (!result) + { + /* If we failed to convert the entire initializer, then we must + leave the structure assignment in place and must load values + from the structure into the slots for which we did not find + constants. The easiest way to do this is to generate a complete + copy-out, and then follow that with the constant assignments + that we were able to build. DCE will clean things up. */ + tree list0 = NULL; + generate_copy_inout (lhs_elt, true, generate_element_ref (lhs_elt), + &list0); + append_to_statement_list (list, &list0); + list = list0; + } - if (lhs_elt->use_block_copy) + if (lhs_elt->use_block_copy || !result) { /* Since LHS is not fully instantiated, we must leave the structure assignment in place. Treating this case differently from a USE exposes constants to later optimizations. */ - mark_all_v_defs (expr_first (list)); - sra_insert_after (bsi, list); + if (list) + { + mark_all_v_defs (expr_first (list)); + sra_insert_after (bsi, list); + } } else { /* The LHS is fully instantiated. The list of initializations replaces the original structure assignment. */ + if (!list) + abort (); mark_all_v_defs (bsi_stmt (*bsi)); sra_replace (bsi, list); } - - return true; } /* A subroutine of scalarize_ldst called via walk_tree. Set TREE_NO_TRAP -- 2.30.2