Commit be384c10 by Martin Jambor Committed by Martin Jambor

re PR debug/54971 (SRA pessimizes debug info by not creating debug stmts for…

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
parent a4bbf910
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
...@@ -227,6 +227,10 @@ struct access ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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
......
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