Commit c4d91f2e by Teresa Johnson Committed by Teresa Johnson

re PR bootstrap/63432 (profiledbootstrap failure with bootstrap-lto)

2014-10-07  Teresa Johnson  <tejohnson@google.com>

	PR bootstrap/63432.
	* tree-ssa-threadupdate.c (estimated_freqs_path): New function.
	(ssa_fix_duplicate_block_edges): Invoke it.
	(mark_threaded_blocks): Make two passes to avoid ordering dependences.

From-SVN: r216024
parent 1a950eea
2014-10-08 Teresa Johnson <tejohnson@google.com>
PR bootstrap/63432.
* tree-ssa-threadupdate.c (estimated_freqs_path): New function.
(ssa_fix_duplicate_block_edges): Invoke it.
(mark_threaded_blocks): Make two passes to avoid ordering dependences.
2014-10-08 Oleg Endo <olegendo@gcc.gnu.org> 2014-10-08 Oleg Endo <olegendo@gcc.gnu.org>
PR target/52941 PR target/52941
...@@ -959,6 +959,43 @@ update_joiner_offpath_counts (edge epath, basic_block dup_bb, ...@@ -959,6 +959,43 @@ update_joiner_offpath_counts (edge epath, basic_block dup_bb,
} }
/* Check if the paths through RD all have estimated frequencies but zero
profile counts. This is more accurate than checking the entry block
for a zero profile count, since profile insanities sometimes creep in. */
static bool
estimated_freqs_path (struct redirection_data *rd)
{
edge e = rd->incoming_edges->e;
vec<jump_thread_edge *> *path = THREAD_PATH (e);
edge ein;
edge_iterator ei;
bool non_zero_freq = false;
FOR_EACH_EDGE (ein, ei, e->dest->preds)
{
if (ein->count)
return false;
non_zero_freq |= ein->src->frequency != 0;
}
for (unsigned int i = 1; i < path->length (); i++)
{
edge epath = (*path)[i]->e;
if (epath->src->count)
return false;
non_zero_freq |= epath->src->frequency != 0;
edge esucc;
FOR_EACH_EDGE (esucc, ei, epath->src->succs)
{
if (esucc->count)
return false;
non_zero_freq |= esucc->src->frequency != 0;
}
}
return non_zero_freq;
}
/* Invoked for routines that have guessed frequencies and no profile /* Invoked for routines that have guessed frequencies and no profile
counts to record the block and edge frequencies for paths through RD counts to record the block and edge frequencies for paths through RD
in the profile count fields of those blocks and edges. This is because in the profile count fields of those blocks and edges. This is because
...@@ -1058,9 +1095,11 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd, ...@@ -1058,9 +1095,11 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd,
data we first take a snapshot of the existing block and edge frequencies data we first take a snapshot of the existing block and edge frequencies
by copying them into the empty profile count fields. These counts are by copying them into the empty profile count fields. These counts are
then used to do the incremental updates, and cleared at the end of this then used to do the incremental updates, and cleared at the end of this
routine. */ routine. If the function is marked as having a profile, we still check
to see if the paths through RD are using estimated frequencies because
the routine had zero profile counts. */
bool do_freqs_to_counts = (profile_status_for_fn (cfun) != PROFILE_READ bool do_freqs_to_counts = (profile_status_for_fn (cfun) != PROFILE_READ
|| !ENTRY_BLOCK_PTR_FOR_FN (cfun)->count); || estimated_freqs_path (rd));
if (do_freqs_to_counts) if (do_freqs_to_counts)
freqs_to_counts_path (rd); freqs_to_counts_path (rd);
...@@ -2077,35 +2116,52 @@ mark_threaded_blocks (bitmap threaded_blocks) ...@@ -2077,35 +2116,52 @@ mark_threaded_blocks (bitmap threaded_blocks)
/* Now iterate again, converting cases where we want to thread /* Now iterate again, converting cases where we want to thread
through a joiner block, but only if no other edge on the path through a joiner block, but only if no other edge on the path
already has a jump thread attached to it. */ already has a jump thread attached to it. We do this in two passes,
to avoid situations where the order in the paths vec can hide overlapping
threads (the path is recorded on the incoming edge, so we would miss
cases where the second path starts at a downstream edge on the same
path). First record all joiner paths, deleting any in the unexpected
case where there is already a path for that incoming edge. */
for (i = 0; i < paths.length (); i++) for (i = 0; i < paths.length (); i++)
{ {
vec<jump_thread_edge *> *path = paths[i]; vec<jump_thread_edge *> *path = paths[i];
if ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK) if ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK)
{
/* Attach the path to the starting edge if none is yet recorded. */
if ((*path)[0]->e->aux == NULL)
(*path)[0]->e->aux = path;
else if (dump_file && (dump_flags & TDF_DETAILS))
dump_jump_thread_path (dump_file, *path, false);
}
}
/* Second, look for paths that have any other jump thread attached to
them, and either finish converting them or cancel them. */
for (i = 0; i < paths.length (); i++)
{
vec<jump_thread_edge *> *path = paths[i];
edge e = (*path)[0]->e;
if ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK && e->aux == path)
{ {
unsigned int j; unsigned int j;
for (j = 1; j < path->length (); j++)
for (j = 0; j < path->length (); j++)
if ((*path)[j]->e->aux != NULL) if ((*path)[j]->e->aux != NULL)
break; break;
/* If we iterated through the entire path without exiting the loop, /* If we iterated through the entire path without exiting the loop,
then we are good to go, attach the path to the starting edge. */ then we are good to go, record it. */
if (j == path->length ()) if (j == path->length ())
bitmap_set_bit (tmp, e->dest->index);
else
{ {
edge e = (*path)[0]->e; e->aux = NULL;
e->aux = path; if (dump_file && (dump_flags & TDF_DETAILS))
bitmap_set_bit (tmp, e->dest->index); dump_jump_thread_path (dump_file, *path, false);
}
else if (dump_file && (dump_flags & TDF_DETAILS))
{
dump_jump_thread_path (dump_file, *path, false);
} }
} }
} }
/* If optimizing for size, only thread through block if we don't have /* If optimizing for size, only thread through block if we don't have
to duplicate it or it's an otherwise empty redirection block. */ to duplicate it or it's an otherwise empty redirection block. */
if (optimize_function_for_size_p (cfun)) if (optimize_function_for_size_p (cfun))
......
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