summaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-28 12:12:51 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-28 12:12:51 +0000
commit4f264c8b1f30ba6c58be89d6015a7b28829cf99f (patch)
treeebd7965dd7e0d7e3491d71a34ab36c403cd68810 /gcc/tree-sra.c
parentd700b485013307105444926a807a33e1a9b2a413 (diff)
downloadgcc-4f264c8b1f30ba6c58be89d6015a7b28829cf99f.tar.gz
* tree-sra.c (is_sra_candidate_ref): Remove second arg; all callers
changed. (is_sra_candidate_complex_ref): New function. (scalarize_modify_expr): Call it and check for LHS also. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83784 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index bbb5942db24..24b2d187c96 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -160,21 +160,13 @@ is_sra_candidate_decl (tree decl)
}
/* Return true if EXP is of the form <ref decl>, where REF is one of the
- field access references we handle and DECL is an SRA candidate.
-
- Set ALLOW_BIT_FIELD_REF to accept BIT_FIELD_REF as well. This is
- normally false, except when we're trying to work around it. */
+ field access references we handle and DECL is an SRA candidate. */
static bool
-is_sra_candidate_ref (tree exp, bool allow_bit_field_ref)
+is_sra_candidate_ref (tree exp)
{
switch (TREE_CODE (exp))
{
- case BIT_FIELD_REF:
- if (!allow_bit_field_ref)
- break;
- /* FALLTHRU */
-
case COMPONENT_REF:
case REALPART_EXPR:
case IMAGPART_EXPR:
@@ -187,6 +179,28 @@ is_sra_candidate_ref (tree exp, bool allow_bit_field_ref)
return false;
}
+/* Return true if EXP is of the form <ref decl>, where REF is a nest of
+ references handled by handle_components_p and DECL is an SRA candidate.
+ *VAR_P is set to DECL. */
+
+static bool
+is_sra_candidate_complex_ref (tree exp, tree *var_p)
+{
+ tree orig_exp = exp;
+
+ while (TREE_CODE (exp) == REALPART_EXPR || TREE_CODE (exp) == IMAGPART_EXPR
+ || handled_component_p (exp))
+ exp = TREE_OPERAND (exp, 0);
+
+ if (orig_exp != exp && is_sra_candidate_decl (exp))
+ {
+ *var_p = exp;
+ return true;
+ }
+
+ return false;
+}
+
/* Return the scalar in SRA_MAP[VAR_IX][FIELD_IX]. If none exists, create
a new scalar with type TYPE. */
@@ -916,9 +930,10 @@ scalarize_modify_expr (block_stmt_iterator *si_p)
tree stmt = bsi_stmt (*si_p);
tree lhs = TREE_OPERAND (stmt, 0);
tree rhs = TREE_OPERAND (stmt, 1);
+ tree var = NULL_TREE;
/* Found AGGREGATE.FIELD = ... */
- if (is_sra_candidate_ref (lhs, false))
+ if (is_sra_candidate_ref (lhs))
{
tree sym;
v_may_def_optype v_may_defs;
@@ -936,10 +951,12 @@ scalarize_modify_expr (block_stmt_iterator *si_p)
}
/* Found ... = AGGREGATE.FIELD */
- else if (is_sra_candidate_ref (rhs, false))
+ else if (is_sra_candidate_ref (rhs))
scalarize_component_ref (stmt, &TREE_OPERAND (stmt, 1));
- /* Found ... = BIT_FIELD_REF <>. This is similar to a CALL_EXPR, if the
+ /* Found a complex reference nesting involving a candidate decl. This
+ should only occur if the above condition is false if a BIT_FIELD_REF or
+ VIEW_CONVERT_EXPR is involved. This is similar to a CALL_EXPR, if the
operand of the BIT_FIELD_REF is a scalarizable structure, we need to
copy from its scalar replacements before doing the bitfield operation.
@@ -951,10 +968,22 @@ scalarize_modify_expr (block_stmt_iterator *si_p)
generates a BIT_FIELD_REF operation for one of the comparisons,
preventing the optimizers from removing all the redundant
operations. */
- else if (is_sra_candidate_ref (rhs, true))
+ else if (is_sra_candidate_complex_ref (rhs, &var))
{
- tree var = TREE_OPERAND (rhs, 0);
emit_scalar_copies (si_p, var, var, FIELD_SCALAR);
+
+ /* If the LHS of the assignment is also a scalarizable structure, insert
+ copies into the scalar replacements after the call. */
+ if (is_sra_candidate_decl (lhs))
+ {
+ tree list = create_scalar_copies (lhs, lhs, SCALAR_FIELD);
+ if (EXPR_HAS_LOCATION (stmt))
+ annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
+ if (stmt_ends_bb_p (stmt))
+ insert_edge_copies (list, bb_for_stmt (stmt));
+ else
+ bsi_insert_after (si_p, list, BSI_NEW_STMT);
+ }
}
/* Found AGGREGATE = ... or ... = AGGREGATE */
@@ -983,7 +1012,7 @@ scalarize_tree_list (tree list, block_stmt_iterator *si_p, bitmap done)
bitmap_set_bit (done, index);
}
}
- else if (is_sra_candidate_ref (arg, false))
+ else if (is_sra_candidate_ref (arg))
{
tree stmt = bsi_stmt (*si_p);
scalarize_component_ref (stmt, &TREE_VALUE (op));
@@ -1071,7 +1100,7 @@ scalarize_return_expr (block_stmt_iterator *si_p)
emit_scalar_copies (si_p, rhs, rhs, FIELD_SCALAR);
/* Handle 'return STRUCTURE.FIELD;' */
- else if (is_sra_candidate_ref (rhs, false))
+ else if (is_sra_candidate_ref (rhs))
scalarize_component_ref (stmt, rhs_p);
/* Handle 'return CALL_EXPR;' */