* update-copyright.py: Skip pdt-5.f03 in gfortran.dg subdir.
[platform/upstream/gcc.git] / gcc / tracer.c
index cecefdc..0c7a953 100644 (file)
@@ -1,7 +1,7 @@
 /* The tracer pass for the GNU compiler.
    Contributed by Jan Hubicka, SuSE Labs.
    Adapted to work on GIMPLE instead of RTL by Robert Kidd, UIUC.
-   Copyright (C) 2001-2014 Free Software Foundation, Inc.
+   Copyright (C) 2001-2017 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
+#include "backend.h"
 #include "rtl.h"
-#include "hard-reg-set.h"
+#include "tree.h"
+#include "gimple.h"
+#include "cfghooks.h"
+#include "tree-pass.h"
 #include "profile.h"
-#include "predict.h"
-#include "vec.h"
-#include "hashtab.h"
-#include "hash-set.h"
-#include "machmode.h"
-#include "input.h"
-#include "function.h"
-#include "dominance.h"
-#include "cfg.h"
 #include "cfganal.h"
-#include "basic-block.h"
-#include "flags.h"
 #include "params.h"
-#include "coverage.h"
-#include "tree-pass.h"
-#include "tree-ssa-alias.h"
-#include "internal-fn.h"
-#include "gimple-expr.h"
-#include "is-a.h"
-#include "gimple.h"
 #include "gimple-iterator.h"
 #include "tree-cfg.h"
 #include "tree-ssa.h"
 #include "tree-inline.h"
 #include "cfgloop.h"
 #include "fibonacci_heap.h"
+#include "tracer.h"
 
 static int count_insns (basic_block);
-static bool ignore_bb_p (const_basic_block);
 static bool better_p (const_edge, const_edge);
 static edge find_best_successor (basic_block);
 static edge find_best_predecessor (basic_block);
@@ -81,7 +65,7 @@ static int branch_ratio_cutoff;
 
 /* A bit BB->index is set if BB has already been seen, i.e. it is
    connected to some trace already.  */
-sbitmap bb_seen;
+static sbitmap bb_seen;
 
 static inline void
 mark_bb_seen (basic_block bb)
@@ -101,21 +85,28 @@ bb_seen_p (basic_block bb)
 }
 
 /* Return true if we should ignore the basic block for purposes of tracing.  */
-static bool
+bool
 ignore_bb_p (const_basic_block bb)
 {
-  gimple g;
-
   if (bb->index < NUM_FIXED_BLOCKS)
     return true;
   if (optimize_bb_for_size_p (bb))
     return true;
 
-  /* A transaction is a single entry multiple exit region.  It must be
-     duplicated in its entirety or not at all.  */
-  g = last_stmt (CONST_CAST_BB (bb));
-  if (g && gimple_code (g) == GIMPLE_TRANSACTION)
-    return true;
+  if (gimple *g = last_stmt (CONST_CAST_BB (bb)))
+    {
+      /* A transaction is a single entry multiple exit region.  It
+        must be duplicated in its entirety or not at all.  */
+      if (gimple_code (g) == GIMPLE_TRANSACTION)
+       return true;
+
+      /* An IFN_UNIQUE call must be duplicated as part of its group,
+        or not at all.  */
+      if (is_gimple_call (g)
+         && gimple_call_internal_p (g)
+         && gimple_call_internal_unique_p (g))
+       return true;
+    }
 
   return false;
 }
@@ -126,7 +117,7 @@ static int
 count_insns (basic_block bb)
 {
   gimple_stmt_iterator gsi;
-  gimple stmt;
+  gimple *stmt;
   int n = 0;
 
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -141,12 +132,9 @@ count_insns (basic_block bb)
 static bool
 better_p (const_edge e1, const_edge e2)
 {
-  if (e1->count != e2->count)
-    return e1->count > e2->count;
-  if (e1->src->frequency * e1->probability !=
-      e2->src->frequency * e2->probability)
-    return (e1->src->frequency * e1->probability
-           > e2->src->frequency * e2->probability);
+  if (e1->count ().initialized_p () && e2->count ().initialized_p ()
+      && ((e1->count () > e2->count ()) || (e1->count () < e2->count  ())))
+    return e1->count () > e2->count ();
   /* This is needed to avoid changes in the decision after
      CFG is modified.  */
   if (e1->src != e2->src)
@@ -168,7 +156,8 @@ find_best_successor (basic_block bb)
       best = e;
   if (!best || ignore_bb_p (best->dest))
     return NULL;
-  if (best->probability <= probability_cutoff)
+  if (best->probability.initialized_p ()
+      && best->probability.to_reg_br_prob_base () <= probability_cutoff)
     return NULL;
   return best;
 }
@@ -188,7 +177,7 @@ find_best_predecessor (basic_block bb)
   if (!best || ignore_bb_p (best->src))
     return NULL;
   if (EDGE_FREQUENCY (best) * REG_BR_PROB_BASE
-      < bb->frequency * branch_ratio_cutoff)
+      < bb->count.to_frequency (cfun) * branch_ratio_cutoff)
     return NULL;
   return best;
 }
@@ -203,7 +192,7 @@ find_trace (basic_block bb, basic_block *trace)
   edge e;
 
   if (dump_file)
-    fprintf (dump_file, "Trace seed %i [%i]", bb->index, bb->frequency);
+    fprintf (dump_file, "Trace seed %i [%i]", bb->index, bb->count.to_frequency (cfun));
 
   while ((e = find_best_predecessor (bb)) != NULL)
     {
@@ -212,11 +201,11 @@ find_trace (basic_block bb, basic_block *trace)
          || find_best_successor (bb2) != e)
        break;
       if (dump_file)
-       fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency);
+       fprintf (dump_file, ",%i [%i]", bb->index, bb->count.to_frequency (cfun));
       bb = bb2;
     }
   if (dump_file)
-    fprintf (dump_file, " forward %i [%i]", bb->index, bb->frequency);
+    fprintf (dump_file, " forward %i [%i]", bb->index, bb->count.to_frequency (cfun));
   trace[i++] = bb;
 
   /* Follow the trace in forward direction.  */
@@ -227,7 +216,7 @@ find_trace (basic_block bb, basic_block *trace)
          || find_best_predecessor (bb) != e)
        break;
       if (dump_file)
-       fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency);
+       fprintf (dump_file, ",%i [%i]", bb->index, bb->count.to_frequency (cfun));
       trace[i++] = bb;
     }
   if (dump_file)
@@ -235,6 +224,24 @@ find_trace (basic_block bb, basic_block *trace)
   return i;
 }
 
+/* Duplicate block BB2, placing it after BB in the CFG.  Return the
+   newly created block.  */
+basic_block
+transform_duplicate (basic_block bb, basic_block bb2)
+{
+  edge e;
+  basic_block copy;
+
+  e = find_edge (bb, bb2);
+
+  copy = duplicate_block (bb2, e, bb);
+  flush_pending_stmts (e);
+
+  add_phi_args_after_copy (&copy, 1, NULL);
+
+  return (copy);
+}
+
 /* Look for basic blocks in frequency order, construct traces and tail duplicate
    if profitable.  */
 
@@ -260,7 +267,7 @@ tail_duplicate (void)
   bitmap_clear (bb_seen);
   initialize_original_copy_tables ();
 
-  if (profile_info && flag_branch_probabilities)
+  if (profile_info && profile_status_for_fn (cfun) == PROFILE_READ)
     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
   else
     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
@@ -273,14 +280,14 @@ tail_duplicate (void)
     {
       int n = count_insns (bb);
       if (!ignore_bb_p (bb))
-       blocks[bb->index] = heap.insert (-bb->frequency, bb);
+       blocks[bb->index] = heap.insert (-bb->count.to_frequency (cfun), bb);
 
       counts [bb->index] = n;
       ninsns += n;
-      weighted_insns += n * bb->frequency;
+      weighted_insns += n * bb->count.to_frequency (cfun);
     }
 
-  if (profile_info && flag_branch_probabilities)
+  if (profile_info && profile_status_for_fn (cfun) == PROFILE_READ)
     cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE_FEEDBACK);
   else
     cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE);
@@ -305,7 +312,7 @@ tail_duplicate (void)
       n = find_trace (bb, trace);
 
       bb = trace[0];
-      traced_insns += bb->frequency * counts [bb->index];
+      traced_insns += bb->count.to_frequency (cfun) * counts [bb->index];
       if (blocks[bb->index])
        {
          heap.delete_node (blocks[bb->index]);
@@ -321,7 +328,7 @@ tail_duplicate (void)
              heap.delete_node (blocks[bb2->index]);
              blocks[bb2->index] = NULL;
            }
-         traced_insns += bb2->frequency * counts [bb2->index];
+         traced_insns += bb2->count.to_frequency (cfun) * counts [bb2->index];
          if (EDGE_COUNT (bb2->preds) > 1
              && can_duplicate_block_p (bb2)
              /* We have the tendency to duplicate the loop header
@@ -330,26 +337,17 @@ tail_duplicate (void)
                 entries or at least rotate the loop.  */
              && bb2->loop_father->header != bb2)
            {
-             edge e;
-             basic_block copy;
-
              nduplicated += counts [bb2->index];
-
-             e = find_edge (bb, bb2);
-
-             copy = duplicate_block (bb2, e, bb);
-             flush_pending_stmts (e);
-
-             add_phi_args_after_copy (&copy, 1, NULL);
+             basic_block copy = transform_duplicate (bb, bb2);
 
              /* Reconsider the original copy of block we've duplicated.
                 Removing the most common predecessor may make it to be
                 head.  */
-             blocks[bb2->index] = heap.insert (-bb2->frequency, bb2);
+             blocks[bb2->index] = heap.insert (-bb2->count.to_frequency (cfun), bb2);
 
              if (dump_file)
                fprintf (dump_file, "Duplicated %i as %i [%i]\n",
-                        bb2->index, copy->index, copy->frequency);
+                        bb2->index, copy->index, copy->count.to_frequency (cfun));
 
              bb2 = copy;
              changed = true;