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>
|
||||
|
||||
* 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. */
|
||||
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? */
|
||||
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_unscalarizable_region = %d, grp_unscalarized_data = %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",
|
||||
access->grp_read, access->grp_write, access->grp_assignment_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_unscalarizable_region, access->grp_unscalarized_data,
|
||||
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);
|
||||
else
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
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
|
||||
@ -1861,7 +1902,13 @@ create_access_replacement (struct access *access)
|
||||
{
|
||||
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
|
||||
|| TREE_CODE (access->type) == VECTOR_TYPE)
|
||||
{
|
||||
@ -1930,12 +1977,22 @@ create_access_replacement (struct access *access)
|
||||
|
||||
if (dump_file)
|
||||
{
|
||||
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");
|
||||
if (access->grp_to_be_debug_replaced)
|
||||
{
|
||||
fprintf (dump_file, "Created a debug-only replacement for ");
|
||||
print_generic_expr (dump_file, access->base, 0);
|
||||
fprintf (dump_file, " offset: %u, size: %u\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++;
|
||||
|
||||
@ -2144,6 +2201,23 @@ analyze_access_subtree (struct access *root, struct access *parent,
|
||||
}
|
||||
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)
|
||||
hole = true;
|
||||
if (scalar)
|
||||
@ -2504,6 +2578,22 @@ generate_subtree_copies (struct access *access, tree agg,
|
||||
update_stmt (stmt);
|
||||
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)
|
||||
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);
|
||||
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)
|
||||
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;
|
||||
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)
|
||||
{
|
||||
@ -2721,10 +2828,11 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
|
||||
location_t loc = gimple_location (gsi_stmt (*old_gsi));
|
||||
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)
|
||||
{
|
||||
struct access *racc;
|
||||
HOST_WIDE_INT offset = lacc->offset - left_offset + top_racc->offset;
|
||||
gimple stmt;
|
||||
tree rhs;
|
||||
|
||||
@ -2764,10 +2872,34 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
|
||||
update_stmt (stmt);
|
||||
sra_stats.subreplacements++;
|
||||
}
|
||||
else if (*refreshed == SRA_UDH_NONE
|
||||
&& lacc->grp_read && !lacc->grp_covered)
|
||||
*refreshed = handle_unscalarized_data_in_subtree (top_racc,
|
||||
old_gsi);
|
||||
else
|
||||
{
|
||||
if (*refreshed == SRA_UDH_NONE
|
||||
&& 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)
|
||||
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
|
||||
aggregates when at least one has scalar reductions of some of its
|
||||
components. There are three possible scenarios: Both the LHS and RHS have
|
||||
|
Loading…
Reference in New Issue
Block a user