Commit bfeebecf by Richard Henderson Committed by Richard Henderson

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
parent 82b5e52a
2004-07-06 Richard Henderson <rth@redhat.com>
* 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 <jsm@polyomino.org.uk> 2004-07-06 Joseph S. Myers <jsm@polyomino.org.uk>
* toplev.h (NO_FRONT_END_DIAG, ATTRIBUTE_GCC_FE_DIAG): Define. * toplev.h (NO_FRONT_END_DIAG, ATTRIBUTE_GCC_FE_DIAG): Define.
......
...@@ -569,9 +569,8 @@ struct sra_walk_fns ...@@ -569,9 +569,8 @@ struct sra_walk_fns
block_stmt_iterator *bsi); block_stmt_iterator *bsi);
/* Invoked when ELT is initialized from a constant. VALUE may be NULL, /* Invoked when ELT is initialized from a constant. VALUE may be NULL,
in which case it should be treated as an empty CONSTRUCTOR. Return in which case it should be treated as an empty CONSTRUCTOR. */
false if we found a case we couldn't handle. */ void (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi);
bool (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi);
/* Invoked when we have a copy between one scalarizable reference ELT /* Invoked when we have a copy between one scalarizable reference ELT
and one non-scalarizable reference OTHER. IS_OUTPUT is true if 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, ...@@ -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 /* If this is an assignment from a constant, or constructor, then
we have access to all of the elements individually. Invoke INIT. */ we have access to all of the elements individually. Invoke INIT. */
if ((TREE_CODE (rhs) == COMPLEX_EXPR if (TREE_CODE (rhs) == COMPLEX_EXPR
|| TREE_CODE (rhs) == COMPLEX_CST || TREE_CODE (rhs) == COMPLEX_CST
|| TREE_CODE (rhs) == CONSTRUCTOR) || TREE_CODE (rhs) == CONSTRUCTOR)
&& fns->init (lhs_elt, rhs, bsi)) fns->init (lhs_elt, rhs, bsi);
;
/* If this is an assignment from read-only memory, treat this as if /* If this is an assignment from read-only memory, treat this as if
we'd been passed the constructor directly. Invoke INIT. */ we'd been passed the constructor directly. Invoke INIT. */
else if (TREE_CODE (rhs) == VAR_DECL else if (TREE_CODE (rhs) == VAR_DECL
&& TREE_STATIC (rhs) && TREE_STATIC (rhs)
&& TREE_READONLY (rhs) && TREE_READONLY (rhs)
&& targetm.binds_local_p (rhs) && targetm.binds_local_p (rhs))
&& DECL_INITIAL (rhs) fns->init (lhs_elt, DECL_INITIAL (rhs), bsi);
&& fns->init (lhs_elt, DECL_INITIAL (rhs), bsi))
;
/* If this is a copy from a non-scalarizable lvalue, invoke LDST. /* If this is a copy from a non-scalarizable lvalue, invoke LDST.
The lvalue requirement prevents us from trying to directly scalarize 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, ...@@ -934,12 +930,11 @@ scan_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
rhs_elt->n_copies += 1; rhs_elt->n_copies += 1;
} }
static bool static void
scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED, scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED,
block_stmt_iterator *bsi ATTRIBUTE_UNUSED) block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
{ {
lhs_elt->n_copies += 1; lhs_elt->n_copies += 1;
return true;
} }
static void static void
...@@ -1490,12 +1485,16 @@ generate_element_zero (struct sra_elt *elt, tree *list_p) ...@@ -1490,12 +1485,16 @@ generate_element_zero (struct sra_elt *elt, tree *list_p)
{ {
struct sra_elt *c; struct sra_elt *c;
if (elt->visited)
{
elt->visited = false;
return;
}
for (c = elt->children; c ; c = c->sibling) for (c = elt->children; c ; c = c->sibling)
generate_element_zero (c, list_p); generate_element_zero (c, list_p);
if (elt->visited) if (elt->replacement)
elt->visited = false;
else if (elt->replacement)
{ {
tree t; tree t;
...@@ -1567,6 +1566,7 @@ generate_element_init (struct sra_elt *elt, tree init, tree *list_p) ...@@ -1567,6 +1566,7 @@ generate_element_init (struct sra_elt *elt, tree init, tree *list_p)
break; break;
default: default:
elt->visited = true;
result = false; result = false;
} }
...@@ -1760,9 +1760,9 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt, ...@@ -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 /* Scalarize an INIT. To recap, this is an assignment to a scalarizable
reference from some form of constructor: CONSTRUCTOR, COMPLEX_CST or reference from some form of constructor: CONSTRUCTOR, COMPLEX_CST or
COMPLEX_EXPR. If RHS is NULL, it should be treated as an empty 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) scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
{ {
bool result = true; bool result = true;
...@@ -1776,28 +1776,41 @@ scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi) ...@@ -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. */ a zero value. Initialize the rest of the instantiated elements. */
generate_element_zero (lhs_elt, &list); generate_element_zero (lhs_elt, &list);
/* If we didn't generate anything or couldn't handle this case return. if (!result)
Say which it was. */ {
if (!result || list == NULL) /* If we failed to convert the entire initializer, then we must
return result; 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 /* Since LHS is not fully instantiated, we must leave the structure
assignment in place. Treating this case differently from a USE assignment in place. Treating this case differently from a USE
exposes constants to later optimizations. */ exposes constants to later optimizations. */
mark_all_v_defs (expr_first (list)); if (list)
sra_insert_after (bsi, list); {
mark_all_v_defs (expr_first (list));
sra_insert_after (bsi, list);
}
} }
else else
{ {
/* The LHS is fully instantiated. The list of initializations /* The LHS is fully instantiated. The list of initializations
replaces the original structure assignment. */ replaces the original structure assignment. */
if (!list)
abort ();
mark_all_v_defs (bsi_stmt (*bsi)); mark_all_v_defs (bsi_stmt (*bsi));
sra_replace (bsi, list); sra_replace (bsi, list);
} }
return true;
} }
/* A subroutine of scalarize_ldst called via walk_tree. Set TREE_NO_TRAP /* A subroutine of scalarize_ldst called via walk_tree. Set TREE_NO_TRAP
......
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