]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH][PR tree-optimization/pr67755] Fix profile insanity adjustments
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Jan 2016 04:17:36 +0000 (04:17 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Jan 2016 04:17:36 +0000 (04:17 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232313 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr67755.c [new file with mode: 0644]
gcc/tree-ssa-threadupdate.c

index 6423a37489c813f17fdbd957496d2cb00c470ce2..f8f818bfb5d0be15969ce01242dce52134dc5d95 100644 (file)
@@ -1,3 +1,14 @@
+2016-01-12  Jeff Law  <law@redhat.com>
+
+       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.
+
 2016-01-12  Sandra Loosemore <sandra@codesourcery.com>
 
        * doc/invoke.texi (Spec Files): Move section down in file, past
index 11f3b0c39b9f70377d3d30fddba2a5db5a44fb9c..240fae713e41c0e7237a7bee24ebc13841224c5a 100644 (file)
@@ -1,4 +1,9 @@
-2015-01-13  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+2016-01-13  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/67755
+       * gcc.dg/tree-ssa/pr67755.c: New test.
+
+2016-01-13  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        * gcc.c-torture/unsorted/dump-noaddr.x (dump_compare): Replace static
        pass number in output by a star.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr67755.c b/gcc/testsuite/gcc.dg/tree-ssa/pr67755.c
new file mode 100644 (file)
index 0000000..64ffd0b
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom2-details-blocks" } */
+/* We want to verify no outgoing edge from a conditional
+   has a probability of 100%.  */
+/* { dg-final { scan-tree-dump-not "succ:\[ \]+. .100.0%.  .\(TRUE|FALSE\)_VALUE" "dom2"} } */
+
+
+void (*zend_block_interruptions) (void);
+
+int * _zend_mm_alloc_int (int * heap, long int size)
+{
+  int *best_fit;
+  long int true_size = (size < 15 ? 32 : size);
+
+  if (zend_block_interruptions)
+    zend_block_interruptions ();
+
+  if (__builtin_expect ((true_size < 543), 1))
+    best_fit = heap + 2;
+  else
+    best_fit = heap;
+
+  return best_fit;
+}
+
index 1bf9ae667721ba8197610f25dc516b8c0bdf0a7f..4783c4b4ea3cd63415da31af2d0df68fe64e2d85 100644 (file)
@@ -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.  */