mirror of git://gcc.gnu.org/git/gcc.git
re PR debug/54971 (SRA pessimizes debug info by not creating debug stmts for fields without replacements)
2012-10-26 Martin Jambor <mjambor@suse.cz> PR debug/54971 * tree-sra.c (struct access): New flag grp_to_be_debug_replaced. (dump_access): Dump the new flag. (analyze_access_subtree): Set the new flag when appropriate. (create_access_replacement): Handle debug replacements differently. (generate_subtree_copies): Handle the grp_to_be_debug_replaced flag. (init_subtree_with_zero): Likewise. (sra_modify_expr): Likewise. (load_assign_lhs_subreplacements): Likewise. (sra_modify_assign): Likewise. From-SVN: r192848
This commit is contained in:
parent
a4bbf9102b
commit
be384c1080
|
|
@ -1,3 +1,16 @@
|
||||||
|
2012-10-26 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
PR debug/54971
|
||||||
|
* tree-sra.c (struct access): New flag grp_to_be_debug_replaced.
|
||||||
|
(dump_access): Dump the new flag.
|
||||||
|
(analyze_access_subtree): Set the new flag when appropriate.
|
||||||
|
(create_access_replacement): Handle debug replacements differently.
|
||||||
|
(generate_subtree_copies): Handle the grp_to_be_debug_replaced flag.
|
||||||
|
(init_subtree_with_zero): Likewise.
|
||||||
|
(sra_modify_expr): Likewise.
|
||||||
|
(load_assign_lhs_subreplacements): Likewise.
|
||||||
|
(sra_modify_assign): Likewise.
|
||||||
|
|
||||||
2012-10-23 Yuri Rumyantsev <ysrumyan@gmail.com>
|
2012-10-23 Yuri Rumyantsev <ysrumyan@gmail.com>
|
||||||
|
|
||||||
* config/i386/i386.c (insn_is_function_arg) : Add check on CALL
|
* config/i386/i386.c (insn_is_function_arg) : Add check on CALL
|
||||||
|
|
|
||||||
167
gcc/tree-sra.c
167
gcc/tree-sra.c
|
|
@ -227,6 +227,10 @@ struct access
|
||||||
/* Set when a scalar replacement should be created for this variable. */
|
/* Set when a scalar replacement should be created for this variable. */
|
||||||
unsigned grp_to_be_replaced : 1;
|
unsigned grp_to_be_replaced : 1;
|
||||||
|
|
||||||
|
/* Set when we want a replacement for the sole purpose of having it in
|
||||||
|
generated debug statements. */
|
||||||
|
unsigned grp_to_be_debug_replaced : 1;
|
||||||
|
|
||||||
/* Should TREE_NO_WARNING of a replacement be set? */
|
/* Should TREE_NO_WARNING of a replacement be set? */
|
||||||
unsigned grp_no_warning : 1;
|
unsigned grp_no_warning : 1;
|
||||||
|
|
||||||
|
|
@ -390,7 +394,7 @@ dump_access (FILE *f, struct access *access, bool grp)
|
||||||
"grp_hint = %d, grp_covered = %d, "
|
"grp_hint = %d, grp_covered = %d, "
|
||||||
"grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
|
"grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
|
||||||
"grp_partial_lhs = %d, grp_to_be_replaced = %d, "
|
"grp_partial_lhs = %d, grp_to_be_replaced = %d, "
|
||||||
"grp_maybe_modified = %d, "
|
"grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
|
||||||
"grp_not_necessarilly_dereferenced = %d\n",
|
"grp_not_necessarilly_dereferenced = %d\n",
|
||||||
access->grp_read, access->grp_write, access->grp_assignment_read,
|
access->grp_read, access->grp_write, access->grp_assignment_read,
|
||||||
access->grp_assignment_write, access->grp_scalar_read,
|
access->grp_assignment_write, access->grp_scalar_read,
|
||||||
|
|
@ -398,7 +402,7 @@ dump_access (FILE *f, struct access *access, bool grp)
|
||||||
access->grp_hint, access->grp_covered,
|
access->grp_hint, access->grp_covered,
|
||||||
access->grp_unscalarizable_region, access->grp_unscalarized_data,
|
access->grp_unscalarizable_region, access->grp_unscalarized_data,
|
||||||
access->grp_partial_lhs, access->grp_to_be_replaced,
|
access->grp_partial_lhs, access->grp_to_be_replaced,
|
||||||
access->grp_maybe_modified,
|
access->grp_to_be_debug_replaced, access->grp_maybe_modified,
|
||||||
access->grp_not_necessarilly_dereferenced);
|
access->grp_not_necessarilly_dereferenced);
|
||||||
else
|
else
|
||||||
fprintf (f, ", write = %d, grp_total_scalarization = %d, "
|
fprintf (f, ", write = %d, grp_total_scalarization = %d, "
|
||||||
|
|
@ -1528,6 +1532,43 @@ build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
|
||||||
gsi, insert_after);
|
gsi, insert_after);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Attempt to build a memory reference that we could but into a gimple
|
||||||
|
debug_bind statement. Similar to build_ref_for_model but punts if it has to
|
||||||
|
create statements and return s NULL instead. This function also ignores
|
||||||
|
alignment issues and so its results should never end up in non-debug
|
||||||
|
statements. */
|
||||||
|
|
||||||
|
static tree
|
||||||
|
build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
|
||||||
|
struct access *model)
|
||||||
|
{
|
||||||
|
HOST_WIDE_INT base_offset;
|
||||||
|
tree off;
|
||||||
|
|
||||||
|
if (TREE_CODE (model->expr) == COMPONENT_REF
|
||||||
|
&& DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
|
||||||
|
return NULL_TREE;
|
||||||
|
|
||||||
|
base = get_addr_base_and_unit_offset (base, &base_offset);
|
||||||
|
if (!base)
|
||||||
|
return NULL_TREE;
|
||||||
|
if (TREE_CODE (base) == MEM_REF)
|
||||||
|
{
|
||||||
|
off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
|
||||||
|
base_offset + offset / BITS_PER_UNIT);
|
||||||
|
off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
|
||||||
|
base = unshare_expr (TREE_OPERAND (base, 0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
off = build_int_cst (reference_alias_ptr_type (base),
|
||||||
|
base_offset + offset / BITS_PER_UNIT);
|
||||||
|
base = build_fold_addr_expr (unshare_expr (base));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fold_build2_loc (loc, MEM_REF, model->type, base, off);
|
||||||
|
}
|
||||||
|
|
||||||
/* Construct a memory reference consisting of component_refs and array_refs to
|
/* Construct a memory reference consisting of component_refs and array_refs to
|
||||||
a part of an aggregate *RES (which is of type TYPE). The requested part
|
a part of an aggregate *RES (which is of type TYPE). The requested part
|
||||||
should have type EXP_TYPE at be the given OFFSET. This function might not
|
should have type EXP_TYPE at be the given OFFSET. This function might not
|
||||||
|
|
@ -1861,7 +1902,13 @@ create_access_replacement (struct access *access)
|
||||||
{
|
{
|
||||||
tree repl;
|
tree repl;
|
||||||
|
|
||||||
repl = create_tmp_var (access->type, "SR");
|
if (access->grp_to_be_debug_replaced)
|
||||||
|
{
|
||||||
|
repl = create_tmp_var_raw (access->type, NULL);
|
||||||
|
DECL_CONTEXT (repl) = current_function_decl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
repl = create_tmp_var (access->type, "SR");
|
||||||
if (TREE_CODE (access->type) == COMPLEX_TYPE
|
if (TREE_CODE (access->type) == COMPLEX_TYPE
|
||||||
|| TREE_CODE (access->type) == VECTOR_TYPE)
|
|| TREE_CODE (access->type) == VECTOR_TYPE)
|
||||||
{
|
{
|
||||||
|
|
@ -1930,12 +1977,22 @@ create_access_replacement (struct access *access)
|
||||||
|
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
{
|
{
|
||||||
fprintf (dump_file, "Created a replacement for ");
|
if (access->grp_to_be_debug_replaced)
|
||||||
print_generic_expr (dump_file, access->base, 0);
|
{
|
||||||
fprintf (dump_file, " offset: %u, size: %u: ",
|
fprintf (dump_file, "Created a debug-only replacement for ");
|
||||||
(unsigned) access->offset, (unsigned) access->size);
|
print_generic_expr (dump_file, access->base, 0);
|
||||||
print_generic_expr (dump_file, repl, 0);
|
fprintf (dump_file, " offset: %u, size: %u\n",
|
||||||
fprintf (dump_file, "\n");
|
(unsigned) access->offset, (unsigned) access->size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (dump_file, "Created a replacement for ");
|
||||||
|
print_generic_expr (dump_file, access->base, 0);
|
||||||
|
fprintf (dump_file, " offset: %u, size: %u: ",
|
||||||
|
(unsigned) access->offset, (unsigned) access->size);
|
||||||
|
print_generic_expr (dump_file, repl, 0);
|
||||||
|
fprintf (dump_file, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sra_stats.replacements++;
|
sra_stats.replacements++;
|
||||||
|
|
||||||
|
|
@ -2144,6 +2201,23 @@ analyze_access_subtree (struct access *root, struct access *parent,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (MAY_HAVE_DEBUG_STMTS && allow_replacements
|
||||||
|
&& scalar && !root->first_child
|
||||||
|
&& (root->grp_scalar_write || root->grp_assignment_write))
|
||||||
|
{
|
||||||
|
gcc_checking_assert (!root->grp_scalar_read
|
||||||
|
&& !root->grp_assignment_read);
|
||||||
|
root->grp_to_be_debug_replaced = 1;
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
{
|
||||||
|
fprintf (dump_file, "Marking ");
|
||||||
|
print_generic_expr (dump_file, root->base, 0);
|
||||||
|
fprintf (dump_file, " offset: %u, size: %u ",
|
||||||
|
(unsigned) root->offset, (unsigned) root->size);
|
||||||
|
fprintf (dump_file, " to be replaced with debug statements.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (covered_to < limit)
|
if (covered_to < limit)
|
||||||
hole = true;
|
hole = true;
|
||||||
if (scalar)
|
if (scalar)
|
||||||
|
|
@ -2504,6 +2578,22 @@ generate_subtree_copies (struct access *access, tree agg,
|
||||||
update_stmt (stmt);
|
update_stmt (stmt);
|
||||||
sra_stats.subtree_copies++;
|
sra_stats.subtree_copies++;
|
||||||
}
|
}
|
||||||
|
else if (write
|
||||||
|
&& access->grp_to_be_debug_replaced
|
||||||
|
&& (chunk_size == 0
|
||||||
|
|| access->offset + access->size > start_offset))
|
||||||
|
{
|
||||||
|
gimple ds;
|
||||||
|
tree drhs = build_debug_ref_for_model (loc, agg,
|
||||||
|
access->offset - top_offset,
|
||||||
|
access);
|
||||||
|
ds = gimple_build_debug_bind (get_access_replacement (access),
|
||||||
|
drhs, gsi_stmt (*gsi));
|
||||||
|
if (insert_after)
|
||||||
|
gsi_insert_after (gsi, ds, GSI_NEW_STMT);
|
||||||
|
else
|
||||||
|
gsi_insert_before (gsi, ds, GSI_SAME_STMT);
|
||||||
|
}
|
||||||
|
|
||||||
if (access->first_child)
|
if (access->first_child)
|
||||||
generate_subtree_copies (access->first_child, agg, top_offset,
|
generate_subtree_copies (access->first_child, agg, top_offset,
|
||||||
|
|
@ -2540,6 +2630,16 @@ init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
|
||||||
update_stmt (stmt);
|
update_stmt (stmt);
|
||||||
gimple_set_location (stmt, loc);
|
gimple_set_location (stmt, loc);
|
||||||
}
|
}
|
||||||
|
else if (access->grp_to_be_debug_replaced)
|
||||||
|
{
|
||||||
|
gimple ds = gimple_build_debug_bind (get_access_replacement (access),
|
||||||
|
build_zero_cst (access->type),
|
||||||
|
gsi_stmt (*gsi));
|
||||||
|
if (insert_after)
|
||||||
|
gsi_insert_after (gsi, ds, GSI_NEW_STMT);
|
||||||
|
else
|
||||||
|
gsi_insert_before (gsi, ds, GSI_SAME_STMT);
|
||||||
|
}
|
||||||
|
|
||||||
for (child = access->first_child; child; child = child->next_sibling)
|
for (child = access->first_child; child; child = child->next_sibling)
|
||||||
init_subtree_with_zero (child, gsi, insert_after, loc);
|
init_subtree_with_zero (child, gsi, insert_after, loc);
|
||||||
|
|
@ -2646,6 +2746,13 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
|
||||||
*expr = repl;
|
*expr = repl;
|
||||||
sra_stats.exprs++;
|
sra_stats.exprs++;
|
||||||
}
|
}
|
||||||
|
else if (write && access->grp_to_be_debug_replaced)
|
||||||
|
{
|
||||||
|
gimple ds = gimple_build_debug_bind (get_access_replacement (access),
|
||||||
|
NULL_TREE,
|
||||||
|
gsi_stmt (*gsi));
|
||||||
|
gsi_insert_after (gsi, ds, GSI_NEW_STMT);
|
||||||
|
}
|
||||||
|
|
||||||
if (access->first_child)
|
if (access->first_child)
|
||||||
{
|
{
|
||||||
|
|
@ -2721,10 +2828,11 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
|
||||||
location_t loc = gimple_location (gsi_stmt (*old_gsi));
|
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;
|
||||||
|
|
||||||
if (lacc->grp_to_be_replaced)
|
if (lacc->grp_to_be_replaced)
|
||||||
{
|
{
|
||||||
struct access *racc;
|
struct access *racc;
|
||||||
HOST_WIDE_INT offset = lacc->offset - left_offset + top_racc->offset;
|
|
||||||
gimple stmt;
|
gimple stmt;
|
||||||
tree rhs;
|
tree rhs;
|
||||||
|
|
||||||
|
|
@ -2764,10 +2872,34 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
|
||||||
update_stmt (stmt);
|
update_stmt (stmt);
|
||||||
sra_stats.subreplacements++;
|
sra_stats.subreplacements++;
|
||||||
}
|
}
|
||||||
else if (*refreshed == SRA_UDH_NONE
|
else
|
||||||
&& lacc->grp_read && !lacc->grp_covered)
|
{
|
||||||
*refreshed = handle_unscalarized_data_in_subtree (top_racc,
|
if (*refreshed == SRA_UDH_NONE
|
||||||
old_gsi);
|
&& lacc->grp_read && !lacc->grp_covered)
|
||||||
|
*refreshed = handle_unscalarized_data_in_subtree (top_racc,
|
||||||
|
old_gsi);
|
||||||
|
if (lacc && lacc->grp_to_be_debug_replaced)
|
||||||
|
{
|
||||||
|
gimple ds;
|
||||||
|
tree drhs;
|
||||||
|
struct access *racc = find_access_in_subtree (top_racc, offset,
|
||||||
|
lacc->size);
|
||||||
|
|
||||||
|
if (racc && racc->grp_to_be_replaced)
|
||||||
|
drhs = get_access_replacement (racc);
|
||||||
|
else if (*refreshed == SRA_UDH_LEFT)
|
||||||
|
drhs = build_debug_ref_for_model (loc, lacc->base, lacc->offset,
|
||||||
|
lacc);
|
||||||
|
else if (*refreshed == SRA_UDH_RIGHT)
|
||||||
|
drhs = build_debug_ref_for_model (loc, top_racc->base, offset,
|
||||||
|
lacc);
|
||||||
|
else
|
||||||
|
drhs = NULL_TREE;
|
||||||
|
ds = gimple_build_debug_bind (get_access_replacement (lacc),
|
||||||
|
drhs, gsi_stmt (*old_gsi));
|
||||||
|
gsi_insert_after (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, top_racc, left_offset,
|
||||||
|
|
@ -2982,6 +3114,13 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lacc && lacc->grp_to_be_debug_replaced)
|
||||||
|
{
|
||||||
|
gimple ds = gimple_build_debug_bind (get_access_replacement (lacc),
|
||||||
|
unshare_expr (rhs), *stmt);
|
||||||
|
gsi_insert_before (gsi, ds, GSI_SAME_STMT);
|
||||||
|
}
|
||||||
|
|
||||||
/* From this point on, the function deals with assignments in between
|
/* From this point on, the function deals with assignments in between
|
||||||
aggregates when at least one has scalar reductions of some of its
|
aggregates when at least one has scalar reductions of some of its
|
||||||
components. There are three possible scenarios: Both the LHS and RHS have
|
components. There are three possible scenarios: Both the LHS and RHS have
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue