re PR tree-optimization/77445 (Performance drop after r239219 on coremark test)
authorJan Hubicka <hubicka@ucw.cz>
Thu, 2 Feb 2017 20:22:13 +0000 (21:22 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 2 Feb 2017 20:22:13 +0000 (20:22 +0000)
PR middle-end/77445
* gcc.dg/tree-ssa/pr77445-2.c: Update testcase to check that all
threading is done.
* tree-ssa-threadbackward.c (profitable_jump_thread_path): Dump
statistics of the analyzed path; allow threading for speed when
any of BBs along the path are optimized for speed.

From-SVN: r245135

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c
gcc/tree-ssa-threadbackward.c

index 7a11db8b0d7592146ec2d017882e8264e683e278..07da434e16673c61c28be5cfac30bc870f1e2fd6 100644 (file)
@@ -1,3 +1,10 @@
+2017-02-02  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR middle-end/77445
+       * tree-ssa-threadbackward.c (profitable_jump_thread_path): Dump
+       statistics of the analyzed path; allow threading for speed when
+       any of BBs along the path are optimized for speed.
+
 2017-02-02  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR middle-end/78468
index 04312df7432847ee31a9b628871049c6d1e72a42..dcc69feae347193622b47f5a439a4fdddc2a7d14 100644 (file)
@@ -1,3 +1,9 @@
+2017-02-02  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR middle-end/77445
+       * gcc.dg/tree-ssa/pr77445-2.c: Update testcase to check that all
+       threading is done.
+
 2017-02-02  Tamar Christina  <tamar.christina@arm.com>
 
        PR middle-end/78142
index 6e576e53ea4ced50d4ad40cd5b6ad098939dd82d..88e3b946fe4e4bf8852c34483935ba0059300446 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-thread1-details-blocks-stats" } */
+/* { dg-options "-O2 -fdump-tree-thread-details-blocks-stats" } */
 typedef enum STATES {
        START=0,
        INVALID,
@@ -121,3 +121,7 @@ enum STATES FMS( u8 **in , u32 *transitions) {
    increase much.  */
 /* { dg-final { scan-tree-dump "Jumps threaded: 1\[1-9\]" "thread1" } } */
 /* { dg-final { scan-tree-dump-times "Invalid sum" 2 "thread1" } } */
+/* { dg-final { scan-tree-dump-not "not considered" "thread1" } } */
+/* { dg-final { scan-tree-dump-not "not considered" "thread2" } } */
+/* { dg-final { scan-tree-dump-not "not considered" "thread3" } } */
+/* { dg-final { scan-tree-dump-not "not considered" "thread4" } } */
index 51f30a7639c7ca9adba1da702438731d0cd08ca8..24def1deed90a873b0b31cc71bc248730bb9c2d3 100644 (file)
@@ -159,6 +159,10 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
   bool threaded_through_latch = false;
   bool multiway_branch_in_path = false;
   bool threaded_multiway_branch = false;
+  bool contains_hot_bb = false;
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    fprintf (dump_file, "Checking profitability of path (backwards): ");
 
   /* Count the number of instructions on the path: as these instructions
      will have to be duplicated, we will not record the path if there
@@ -168,6 +172,8 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
     {
       basic_block bb = (*path)[j];
 
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       fprintf (dump_file, " bb:%i", bb->index);
       /* Remember, blocks in the path are stored in opposite order
         in the PATH array.  The last entry in the array represents
         the block with an outgoing edge that we will redirect to the
@@ -177,6 +183,7 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
         branch.  */
       if (j < path_length - 1)
        {
+         int orig_n_insns = n_insns;
          if (bb->loop_father != loop)
            {
              path_crosses_loops = true;
@@ -219,6 +226,8 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
                }
            }
 
+         if (!contains_hot_bb && speed_p)
+           contains_hot_bb |= optimize_bb_for_speed_p (bb);
          for (gsi = gsi_after_labels (bb);
               !gsi_end_p (gsi);
               gsi_next_nondebug (&gsi))
@@ -229,8 +238,10 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
                  && !(gimple_code (stmt) == GIMPLE_ASSIGN
                       && gimple_assign_rhs_code (stmt) == ASSERT_EXPR)
                  && !is_gimple_debug (stmt))
-               n_insns += estimate_num_insns (stmt, &eni_size_weights);
+               n_insns += estimate_num_insns (stmt, &eni_size_weights);
            }
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           fprintf (dump_file, " (%i insns)", n_insns-orig_n_insns);
 
          /* We do not look at the block with the threaded branch
             in this loop.  So if any block with a last statement that
@@ -264,7 +275,13 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
      last block in the threading path.  So don't count it against our
      statement count.  */
 
-  n_insns-= estimate_num_insns (stmt, &eni_size_weights);
+  int stmt_insns = estimate_num_insns (stmt, &eni_size_weights);
+  n_insns-= stmt_insns;
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    fprintf (dump_file, "\n  Control statement insns: %i\n"
+            "  Overall: %i insns\n",
+            stmt_insns, n_insns);
 
   /* We have found a constant value for ARG.  For GIMPLE_SWITCH
      and GIMPLE_GOTO, we use it as-is.  However, for a GIMPLE_COND
@@ -311,7 +328,11 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
       return NULL;
     }
 
-  if (speed_p && optimize_edge_for_speed_p (taken_edge))
+  /* Threading is profitable if the path duplicated is hot but also
+     in a case we separate cold path from hot path and permit optimization
+     of the hot path later.  Be on the agressive side here. In some testcases,
+     as in PR 78407 this leads to noticeable improvements.  */
+  if (speed_p && (optimize_edge_for_speed_p (taken_edge) || contains_hot_bb))
     {
       if (n_insns >= PARAM_VALUE (PARAM_MAX_FSM_THREAD_PATH_INSNS))
        {