tree-sra.c (sra_modify_expr): Generate new memory accesses with same alias type as the original statement.
2014-04-28 Martin Jambor <mjambor@suse.cz> * tree-sra.c (sra_modify_expr): Generate new memory accesses with same alias type as the original statement. (subreplacement_assignment_data): New type. (handle_unscalarized_data_in_subtree): New type of parameter, generate new memory accesses with same alias type as the original statement. (load_assign_lhs_subreplacements): Likewise. (sra_modify_constructor_assign): Generate new memory accesses with same alias type as the original statement. testsuite/ * gcc.dg/tree-ssa/sra-14.c: New test. From-SVN: r209868
This commit is contained in:
parent
9358288555
commit
28151221b5
4 changed files with 187 additions and 76 deletions
|
@ -1,3 +1,15 @@
|
||||||
|
2014-04-28 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
* tree-sra.c (sra_modify_expr): Generate new memory accesses with
|
||||||
|
same alias type as the original statement.
|
||||||
|
(subreplacement_assignment_data): New type.
|
||||||
|
(handle_unscalarized_data_in_subtree): New type of parameter,
|
||||||
|
generate new memory accesses with same alias type as the original
|
||||||
|
statement.
|
||||||
|
(load_assign_lhs_subreplacements): Likewise.
|
||||||
|
(sra_modify_constructor_assign): Generate new memory accesses with
|
||||||
|
same alias type as the original statement.
|
||||||
|
|
||||||
2014-04-28 Richard Biener <rguenther@suse.de>
|
2014-04-28 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
* tree-pass.h (TODO_verify_il): Define.
|
* tree-pass.h (TODO_verify_il): Define.
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2014-04-28 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
* gcc.dg/tree-ssa/sra-14.c: New test.
|
||||||
|
|
||||||
2014-04-28 Richard Biener <rguenther@suse.de>
|
2014-04-28 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR middle-end/60092
|
PR middle-end/60092
|
||||||
|
|
70
gcc/testsuite/gcc.dg/tree-ssa/sra-14.c
Normal file
70
gcc/testsuite/gcc.dg/tree-ssa/sra-14.c
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-options "-O1" } */
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Z
|
||||||
|
{
|
||||||
|
struct S d, s;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S __attribute__ ((noinline, noclone))
|
||||||
|
get_s (void)
|
||||||
|
{
|
||||||
|
struct S s;
|
||||||
|
s.i = 5;
|
||||||
|
s.j = 6;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S __attribute__ ((noinline, noclone))
|
||||||
|
get_d (void)
|
||||||
|
{
|
||||||
|
struct S d;
|
||||||
|
d.i = 0;
|
||||||
|
d.j = 0;
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __attribute__ ((noinline, noclone))
|
||||||
|
get_c (void)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __attribute__ ((noinline, noclone))
|
||||||
|
my_nop (int i)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __attribute__ ((noinline, noclone))
|
||||||
|
foo (void)
|
||||||
|
{
|
||||||
|
struct Z z;
|
||||||
|
int i, c = get_c ();
|
||||||
|
|
||||||
|
z.d = get_d ();
|
||||||
|
z.s = get_s ();
|
||||||
|
|
||||||
|
for (i = 0; i < c; i++)
|
||||||
|
{
|
||||||
|
z.s.i = my_nop (z.s.i);
|
||||||
|
z.s.j = my_nop (z.s.j);
|
||||||
|
}
|
||||||
|
|
||||||
|
return z.s.i + z.s.j;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (foo () != 11)
|
||||||
|
__builtin_abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
177
gcc/tree-sra.c
177
gcc/tree-sra.c
|
@ -2769,7 +2769,7 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
|
||||||
{
|
{
|
||||||
location_t loc;
|
location_t loc;
|
||||||
struct access *access;
|
struct access *access;
|
||||||
tree type, bfr;
|
tree type, bfr, orig_expr;
|
||||||
|
|
||||||
if (TREE_CODE (*expr) == BIT_FIELD_REF)
|
if (TREE_CODE (*expr) == BIT_FIELD_REF)
|
||||||
{
|
{
|
||||||
|
@ -2785,6 +2785,7 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
|
||||||
if (!access)
|
if (!access)
|
||||||
return false;
|
return false;
|
||||||
type = TREE_TYPE (*expr);
|
type = TREE_TYPE (*expr);
|
||||||
|
orig_expr = *expr;
|
||||||
|
|
||||||
loc = gimple_location (gsi_stmt (*gsi));
|
loc = gimple_location (gsi_stmt (*gsi));
|
||||||
gimple_stmt_iterator alt_gsi = gsi_none ();
|
gimple_stmt_iterator alt_gsi = gsi_none ();
|
||||||
|
@ -2811,8 +2812,7 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
|
||||||
{
|
{
|
||||||
tree ref;
|
tree ref;
|
||||||
|
|
||||||
ref = build_ref_for_model (loc, access->base, access->offset, access,
|
ref = build_ref_for_model (loc, orig_expr, 0, access, NULL, false);
|
||||||
NULL, false);
|
|
||||||
|
|
||||||
if (write)
|
if (write)
|
||||||
{
|
{
|
||||||
|
@ -2863,7 +2863,7 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
|
||||||
else
|
else
|
||||||
start_offset = chunk_size = 0;
|
start_offset = chunk_size = 0;
|
||||||
|
|
||||||
generate_subtree_copies (access->first_child, access->base, 0,
|
generate_subtree_copies (access->first_child, orig_expr, access->offset,
|
||||||
start_offset, chunk_size, gsi, write, write,
|
start_offset, chunk_size, gsi, write, write,
|
||||||
loc);
|
loc);
|
||||||
}
|
}
|
||||||
|
@ -2877,53 +2877,70 @@ enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
|
||||||
SRA_UDH_RIGHT, /* Data flushed to the RHS. */
|
SRA_UDH_RIGHT, /* Data flushed to the RHS. */
|
||||||
SRA_UDH_LEFT }; /* Data flushed to the LHS. */
|
SRA_UDH_LEFT }; /* Data flushed to the LHS. */
|
||||||
|
|
||||||
|
struct subreplacement_assignment_data
|
||||||
|
{
|
||||||
|
/* Offset of the access representing the lhs of the assignment. */
|
||||||
|
HOST_WIDE_INT left_offset;
|
||||||
|
|
||||||
|
/* LHS and RHS of the original assignment. */
|
||||||
|
tree assignment_lhs, assignment_rhs;
|
||||||
|
|
||||||
|
/* Access representing the rhs of the whole assignment. */
|
||||||
|
struct access *top_racc;
|
||||||
|
|
||||||
|
/* Stmt iterator used for statement insertions after the original assignment.
|
||||||
|
It points to the main GSI used to traverse a BB during function body
|
||||||
|
modification. */
|
||||||
|
gimple_stmt_iterator *new_gsi;
|
||||||
|
|
||||||
|
/* Stmt iterator used for statement insertions before the original
|
||||||
|
assignment. Keeps on pointing to the original statement. */
|
||||||
|
gimple_stmt_iterator old_gsi;
|
||||||
|
|
||||||
|
/* Location of the assignment. */
|
||||||
|
location_t loc;
|
||||||
|
|
||||||
|
/* Keeps the information whether we have needed to refresh replacements of
|
||||||
|
the LHS and from which side of the assignments this takes place. */
|
||||||
|
enum unscalarized_data_handling refreshed;
|
||||||
|
};
|
||||||
|
|
||||||
/* Store all replacements in the access tree rooted in TOP_RACC either to their
|
/* Store all replacements in the access tree rooted in TOP_RACC either to their
|
||||||
base aggregate if there are unscalarized data or directly to LHS of the
|
base aggregate if there are unscalarized data or directly to LHS of the
|
||||||
statement that is pointed to by GSI otherwise. */
|
statement that is pointed to by GSI otherwise. */
|
||||||
|
|
||||||
static enum unscalarized_data_handling
|
static void
|
||||||
handle_unscalarized_data_in_subtree (struct access *top_racc,
|
handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
|
||||||
gimple_stmt_iterator *gsi)
|
|
||||||
{
|
{
|
||||||
if (top_racc->grp_unscalarized_data)
|
tree src;
|
||||||
|
if (sad->top_racc->grp_unscalarized_data)
|
||||||
{
|
{
|
||||||
generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
|
src = sad->assignment_rhs;
|
||||||
gsi, false, false,
|
sad->refreshed = SRA_UDH_RIGHT;
|
||||||
gimple_location (gsi_stmt (*gsi)));
|
|
||||||
return SRA_UDH_RIGHT;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tree lhs = gimple_assign_lhs (gsi_stmt (*gsi));
|
src = sad->assignment_lhs;
|
||||||
generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
|
sad->refreshed = SRA_UDH_LEFT;
|
||||||
0, 0, gsi, false, false,
|
|
||||||
gimple_location (gsi_stmt (*gsi)));
|
|
||||||
return SRA_UDH_LEFT;
|
|
||||||
}
|
}
|
||||||
|
generate_subtree_copies (sad->top_racc->first_child, src,
|
||||||
|
sad->top_racc->offset, 0, 0,
|
||||||
|
&sad->old_gsi, false, false, sad->loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Try to generate statements to load all sub-replacements in an access subtree
|
/* Try to generate statements to load all sub-replacements in an access subtree
|
||||||
formed by children of LACC from scalar replacements in the TOP_RACC subtree.
|
formed by children of LACC from scalar replacements in the SAD->top_racc
|
||||||
If that is not possible, refresh the TOP_RACC base aggregate and load the
|
subtree. If that is not possible, refresh the SAD->top_racc base aggregate
|
||||||
accesses from it. LEFT_OFFSET is the offset of the left whole subtree being
|
and load the accesses from it. */
|
||||||
copied. NEW_GSI is stmt iterator used for statement insertions after the
|
|
||||||
original assignment, OLD_GSI is used to insert statements before the
|
|
||||||
assignment. *REFRESHED keeps the information whether we have needed to
|
|
||||||
refresh replacements of the LHS and from which side of the assignments this
|
|
||||||
takes place. */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
|
load_assign_lhs_subreplacements (struct access *lacc,
|
||||||
HOST_WIDE_INT left_offset,
|
struct subreplacement_assignment_data *sad)
|
||||||
gimple_stmt_iterator *old_gsi,
|
|
||||||
gimple_stmt_iterator *new_gsi,
|
|
||||||
enum unscalarized_data_handling *refreshed)
|
|
||||||
{
|
{
|
||||||
location_t loc = gimple_location (gsi_stmt (*old_gsi));
|
|
||||||
for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
|
for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
|
||||||
{
|
{
|
||||||
HOST_WIDE_INT offset = lacc->offset - left_offset + top_racc->offset;
|
HOST_WIDE_INT offset;
|
||||||
|
offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
|
||||||
|
|
||||||
if (lacc->grp_to_be_replaced)
|
if (lacc->grp_to_be_replaced)
|
||||||
{
|
{
|
||||||
|
@ -2931,53 +2948,57 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
|
||||||
gimple stmt;
|
gimple stmt;
|
||||||
tree rhs;
|
tree rhs;
|
||||||
|
|
||||||
racc = find_access_in_subtree (top_racc, offset, lacc->size);
|
racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
|
||||||
if (racc && racc->grp_to_be_replaced)
|
if (racc && racc->grp_to_be_replaced)
|
||||||
{
|
{
|
||||||
rhs = get_access_replacement (racc);
|
rhs = get_access_replacement (racc);
|
||||||
if (!useless_type_conversion_p (lacc->type, racc->type))
|
if (!useless_type_conversion_p (lacc->type, racc->type))
|
||||||
rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
|
rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
|
||||||
|
lacc->type, rhs);
|
||||||
|
|
||||||
if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
|
if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
|
||||||
rhs = force_gimple_operand_gsi (old_gsi, rhs, true, NULL_TREE,
|
rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
|
||||||
true, GSI_SAME_STMT);
|
NULL_TREE, true, GSI_SAME_STMT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No suitable access on the right hand side, need to load from
|
/* No suitable access on the right hand side, need to load from
|
||||||
the aggregate. See if we have to update it first... */
|
the aggregate. See if we have to update it first... */
|
||||||
if (*refreshed == SRA_UDH_NONE)
|
if (sad->refreshed == SRA_UDH_NONE)
|
||||||
*refreshed = handle_unscalarized_data_in_subtree (top_racc,
|
handle_unscalarized_data_in_subtree (sad);
|
||||||
old_gsi);
|
|
||||||
|
|
||||||
if (*refreshed == SRA_UDH_LEFT)
|
if (sad->refreshed == SRA_UDH_LEFT)
|
||||||
rhs = build_ref_for_model (loc, lacc->base, lacc->offset, lacc,
|
rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
|
||||||
new_gsi, true);
|
lacc->offset - sad->left_offset,
|
||||||
|
lacc, sad->new_gsi, true);
|
||||||
else
|
else
|
||||||
rhs = build_ref_for_model (loc, top_racc->base, offset, lacc,
|
rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
|
||||||
new_gsi, true);
|
lacc->offset - sad->left_offset,
|
||||||
|
lacc, sad->new_gsi, true);
|
||||||
if (lacc->grp_partial_lhs)
|
if (lacc->grp_partial_lhs)
|
||||||
rhs = force_gimple_operand_gsi (new_gsi, rhs, true, NULL_TREE,
|
rhs = force_gimple_operand_gsi (sad->new_gsi,
|
||||||
|
rhs, true, NULL_TREE,
|
||||||
false, GSI_NEW_STMT);
|
false, GSI_NEW_STMT);
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
|
stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
|
||||||
gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
|
gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
|
||||||
gimple_set_location (stmt, loc);
|
gimple_set_location (stmt, sad->loc);
|
||||||
update_stmt (stmt);
|
update_stmt (stmt);
|
||||||
sra_stats.subreplacements++;
|
sra_stats.subreplacements++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*refreshed == SRA_UDH_NONE
|
if (sad->refreshed == SRA_UDH_NONE
|
||||||
&& lacc->grp_read && !lacc->grp_covered)
|
&& lacc->grp_read && !lacc->grp_covered)
|
||||||
*refreshed = handle_unscalarized_data_in_subtree (top_racc,
|
handle_unscalarized_data_in_subtree (sad);
|
||||||
old_gsi);
|
|
||||||
if (lacc && lacc->grp_to_be_debug_replaced)
|
if (lacc && lacc->grp_to_be_debug_replaced)
|
||||||
{
|
{
|
||||||
gimple ds;
|
gimple ds;
|
||||||
tree drhs;
|
tree drhs;
|
||||||
struct access *racc = find_access_in_subtree (top_racc, offset,
|
struct access *racc = find_access_in_subtree (sad->top_racc,
|
||||||
|
offset,
|
||||||
lacc->size);
|
lacc->size);
|
||||||
|
|
||||||
if (racc && racc->grp_to_be_replaced)
|
if (racc && racc->grp_to_be_replaced)
|
||||||
|
@ -2987,27 +3008,26 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
|
||||||
else
|
else
|
||||||
drhs = NULL;
|
drhs = NULL;
|
||||||
}
|
}
|
||||||
else if (*refreshed == SRA_UDH_LEFT)
|
else if (sad->refreshed == SRA_UDH_LEFT)
|
||||||
drhs = build_debug_ref_for_model (loc, lacc->base, lacc->offset,
|
drhs = build_debug_ref_for_model (sad->loc, lacc->base,
|
||||||
lacc);
|
lacc->offset, lacc);
|
||||||
else if (*refreshed == SRA_UDH_RIGHT)
|
else if (sad->refreshed == SRA_UDH_RIGHT)
|
||||||
drhs = build_debug_ref_for_model (loc, top_racc->base, offset,
|
drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
|
||||||
lacc);
|
offset, lacc);
|
||||||
else
|
else
|
||||||
drhs = NULL_TREE;
|
drhs = NULL_TREE;
|
||||||
if (drhs
|
if (drhs
|
||||||
&& !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
|
&& !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
|
||||||
drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
|
drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
|
||||||
lacc->type, drhs);
|
lacc->type, drhs);
|
||||||
ds = gimple_build_debug_bind (get_access_replacement (lacc),
|
ds = gimple_build_debug_bind (get_access_replacement (lacc),
|
||||||
drhs, gsi_stmt (*old_gsi));
|
drhs, gsi_stmt (sad->old_gsi));
|
||||||
gsi_insert_after (new_gsi, ds, GSI_NEW_STMT);
|
gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lacc->first_child)
|
if (lacc->first_child)
|
||||||
load_assign_lhs_subreplacements (lacc, top_racc, left_offset,
|
load_assign_lhs_subreplacements (lacc, sad);
|
||||||
old_gsi, new_gsi, refreshed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3053,7 +3073,7 @@ sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
|
||||||
/* I have never seen this code path trigger but if it can happen the
|
/* I have never seen this code path trigger but if it can happen the
|
||||||
following should handle it gracefully. */
|
following should handle it gracefully. */
|
||||||
if (access_has_children_p (acc))
|
if (access_has_children_p (acc))
|
||||||
generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
|
generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
|
||||||
true, true, loc);
|
true, true, loc);
|
||||||
return SRA_AM_MODIFIED;
|
return SRA_AM_MODIFIED;
|
||||||
}
|
}
|
||||||
|
@ -3261,7 +3281,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
|
||||||
|| stmt_ends_bb_p (*stmt))
|
|| stmt_ends_bb_p (*stmt))
|
||||||
{
|
{
|
||||||
if (access_has_children_p (racc))
|
if (access_has_children_p (racc))
|
||||||
generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
|
generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
|
||||||
gsi, false, false, loc);
|
gsi, false, false, loc);
|
||||||
if (access_has_children_p (lacc))
|
if (access_has_children_p (lacc))
|
||||||
{
|
{
|
||||||
|
@ -3271,7 +3291,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
|
||||||
alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
|
alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
|
||||||
gsi = &alt_gsi;
|
gsi = &alt_gsi;
|
||||||
}
|
}
|
||||||
generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
|
generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
|
||||||
gsi, true, true, loc);
|
gsi, true, true, loc);
|
||||||
}
|
}
|
||||||
sra_stats.separate_lhs_rhs_handling++;
|
sra_stats.separate_lhs_rhs_handling++;
|
||||||
|
@ -3301,21 +3321,26 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
|
||||||
&& !lacc->grp_unscalarizable_region
|
&& !lacc->grp_unscalarizable_region
|
||||||
&& !racc->grp_unscalarizable_region)
|
&& !racc->grp_unscalarizable_region)
|
||||||
{
|
{
|
||||||
gimple_stmt_iterator orig_gsi = *gsi;
|
struct subreplacement_assignment_data sad;
|
||||||
enum unscalarized_data_handling refreshed;
|
|
||||||
|
sad.left_offset = lacc->offset;
|
||||||
|
sad.assignment_lhs = lhs;
|
||||||
|
sad.assignment_rhs = rhs;
|
||||||
|
sad.top_racc = racc;
|
||||||
|
sad.old_gsi = *gsi;
|
||||||
|
sad.new_gsi = gsi;
|
||||||
|
sad.loc = gimple_location (*stmt);
|
||||||
|
sad.refreshed = SRA_UDH_NONE;
|
||||||
|
|
||||||
if (lacc->grp_read && !lacc->grp_covered)
|
if (lacc->grp_read && !lacc->grp_covered)
|
||||||
refreshed = handle_unscalarized_data_in_subtree (racc, gsi);
|
handle_unscalarized_data_in_subtree (&sad);
|
||||||
else
|
|
||||||
refreshed = SRA_UDH_NONE;
|
|
||||||
|
|
||||||
load_assign_lhs_subreplacements (lacc, racc, lacc->offset,
|
load_assign_lhs_subreplacements (lacc, &sad);
|
||||||
&orig_gsi, gsi, &refreshed);
|
if (sad.refreshed != SRA_UDH_RIGHT)
|
||||||
if (refreshed != SRA_UDH_RIGHT)
|
|
||||||
{
|
{
|
||||||
gsi_next (gsi);
|
gsi_next (gsi);
|
||||||
unlink_stmt_vdef (*stmt);
|
unlink_stmt_vdef (*stmt);
|
||||||
gsi_remove (&orig_gsi, true);
|
gsi_remove (&sad.old_gsi, true);
|
||||||
release_defs (*stmt);
|
release_defs (*stmt);
|
||||||
sra_stats.deleted++;
|
sra_stats.deleted++;
|
||||||
return SRA_AM_REMOVED;
|
return SRA_AM_REMOVED;
|
||||||
|
@ -3344,7 +3369,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
|
||||||
/* Restore the aggregate RHS from its components so the
|
/* Restore the aggregate RHS from its components so the
|
||||||
prevailing aggregate copy does the right thing. */
|
prevailing aggregate copy does the right thing. */
|
||||||
if (access_has_children_p (racc))
|
if (access_has_children_p (racc))
|
||||||
generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
|
generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
|
||||||
gsi, false, false, loc);
|
gsi, false, false, loc);
|
||||||
/* Re-load the components of the aggregate copy destination.
|
/* Re-load the components of the aggregate copy destination.
|
||||||
But use the RHS aggregate to load from to expose more
|
But use the RHS aggregate to load from to expose more
|
||||||
|
|
Loading…
Add table
Reference in a new issue