aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-threadupdate.c
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>2016-01-12 21:17:36 -0700
committerJeff Law <law@gcc.gnu.org>2016-01-12 21:17:36 -0700
commitc6f72a46146142e8d9689e160a7d7d9d9bd227de (patch)
tree758193d840df21e1ce09bb65de351fbb5fdf40b7 /gcc/tree-ssa-threadupdate.c
parent5ee4820a1f12d7b36712d46aab7e57efc61e2537 (diff)
downloadgcc-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.c21
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. */