diff options
author | Jeff Law <law@gcc.gnu.org> | 2016-01-12 21:17:36 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2016-01-12 21:17:36 -0700 |
commit | c6f72a46146142e8d9689e160a7d7d9d9bd227de (patch) | |
tree | 758193d840df21e1ce09bb65de351fbb5fdf40b7 /gcc/tree-ssa-threadupdate.c | |
parent | 5ee4820a1f12d7b36712d46aab7e57efc61e2537 (diff) | |
download | gcc-c6f72a46146142e8d9689e160a7d7d9d9bd227de.zip gcc-c6f72a46146142e8d9689e160a7d7d9d9bd227de.tar.gz gcc-c6f72a46146142e8d9689e160a7d7d9d9bd227de.tar.bz2 |
[PATCH][PR tree-optimization/pr67755] Fix profile insanity adjustments
PR tree-optimization/pr67755
* tree-ssa-threadupdate.c (struct ssa_local_info_t): Add new field
"need_profile_correction".
(thread_block_1): Initialize new field to false by default. If we
have multiple thread paths through a common joiner to different
final targets, then set new field to true.
(compute_path_counts): Only do count adjustment when it's really
needed.
PR tree-optimization/67755
* gcc.dg/tree-ssa/pr67755.c: New test.
From-SVN: r232313
Diffstat (limited to 'gcc/tree-ssa-threadupdate.c')
-rw-r--r-- | gcc/tree-ssa-threadupdate.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 1bf9ae6..4783c4b 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -239,6 +239,11 @@ struct ssa_local_info_t /* Blocks duplicated for the thread. */ bitmap duplicate_blocks; + + /* When we have multiple paths through a joiner which reach different + final destinations, then we may need to correct for potential + profile insanities. */ + bool need_profile_correction; }; /* Passes which use the jump threading code register jump threading @@ -826,7 +831,8 @@ compute_path_counts (struct redirection_data *rd, So ensure that this path's path_out_count is at least the difference between elast->count and nonpath_count. Otherwise the edge counts after threading will not be sane. */ - if (has_joiner && path_out_count < elast->count - nonpath_count) + if (local_info->need_profile_correction + && has_joiner && path_out_count < elast->count - nonpath_count) { path_out_count = elast->count - nonpath_count; /* But neither can we go above the minimum count along the path @@ -1492,6 +1498,7 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners) ssa_local_info_t local_info; local_info.duplicate_blocks = BITMAP_ALLOC (NULL); + local_info.need_profile_correction = false; /* To avoid scanning a linear array for the element we need we instead use a hash table. For normal code there should be no noticeable @@ -1502,6 +1509,7 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners) /* Record each unique threaded destination into a hash table for efficient lookups. */ + edge last = NULL; FOR_EACH_EDGE (e, ei, bb->preds) { if (e->aux == NULL) @@ -1555,6 +1563,17 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners) /* Insert the outgoing edge into the hash table if it is not already in the hash table. */ lookup_redirection_data (e, INSERT); + + /* When we have thread paths through a common joiner with different + final destinations, then we may need corrections to deal with + profile insanities. See the big comment before compute_path_counts. */ + if ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK) + { + if (!last) + last = e2; + else if (e2 != last) + local_info.need_profile_correction = true; + } } /* We do not update dominance info. */ |