]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cfghooks.c
libgo: update to Go 1.12.2
[thirdparty/gcc.git] / gcc / cfghooks.c
index 1b3f2695b3905780c623bc60963dd394d7c9a91f..a1d603a207ec7791a3101060e1126c395507ea62 100644 (file)
@@ -1,5 +1,5 @@
 /* Hooks for cfg representation specific functions.
-   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   Copyright (C) 2003-2019 Free Software Foundation, Inc.
    Contributed by Sebastian Pop <s.pop@laposte.net>
 
 This file is part of GCC.
@@ -146,12 +146,15 @@ verify_flow_info (void)
          error ("verify_flow_info: Wrong count of block %i", bb->index);
          err = 1;
        }
-      if (bb->frequency < 0)
+      /* FIXME: Graphite and SLJL and target code still tends to produce
+        edges with no probablity.  */
+      if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
+          && !bb->count.initialized_p () && !flag_graphite && 0)
        {
-         error ("verify_flow_info: Wrong frequency of block %i %i",
-                bb->index, bb->frequency);
+         error ("verify_flow_info: Missing count of block %i", bb->index);
          err = 1;
        }
+
       FOR_EACH_EDGE (e, ei, bb->succs)
        {
          if (last_visited [e->dest->index] == bb)
@@ -160,15 +163,18 @@ verify_flow_info (void)
                     e->src->index, e->dest->index);
              err = 1;
            }
-         if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
+         /* FIXME: Graphite and SLJL and target code still tends to produce
+            edges with no probablity.  */
+         if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
+             && !e->probability.initialized_p () && !flag_graphite && 0)
            {
-             error ("verify_flow_info: Wrong probability of edge %i->%i %i",
-                    e->src->index, e->dest->index, e->probability);
+             error ("Uninitialized probability of edge %i->%i", e->src->index,
+                    e->dest->index);
              err = 1;
            }
-         if (!e->count.verify ())
+         if (!e->probability.verify ())
            {
-             error ("verify_flow_info: Wrong count of edge %i->%i",
+             error ("verify_flow_info: Wrong probability of edge %i->%i",
                     e->src->index, e->dest->index);
              err = 1;
            }
@@ -282,7 +288,7 @@ dump_bb (FILE *outf, basic_block bb, int indent, dump_flags_t flags)
 DEBUG_FUNCTION void
 debug (basic_block_def &ref)
 {
-  dump_bb (stderr, &ref, 0, 0);
+  dump_bb (stderr, &ref, 0, TDF_NONE);
 }
 
 DEBUG_FUNCTION void
@@ -294,6 +300,14 @@ debug (basic_block_def *ptr)
     fprintf (stderr, "<nil>\n");
 }
 
+static void
+debug_slim (basic_block ptr)
+{
+  fprintf (stderr, "<basic_block %p (%d)>", (void *) ptr, ptr->index);
+}
+
+DEFINE_DEBUG_VEC (basic_block_def *)
+DEFINE_DEBUG_HASH_SET (basic_block_def *)
 
 /* Dumps basic block BB to pretty-printer PP, for use as a label of
    a DOT graph record-node.  The implementation of this hook is
@@ -311,7 +325,6 @@ dump_bb_for_graph (pretty_printer *pp, basic_block bb)
   /* TODO: Add pretty printer for counter.  */
   if (bb->count.initialized_p ())
     pp_printf (pp, "COUNT:" "%" PRId64, bb->count.to_gcov_type ());
-  pp_printf (pp, " FREQ:%i |", bb->frequency);
   pp_write_text_to_stream (pp);
   if (!(dump_flags & TDF_SLIM))
     cfg_hooks->dump_bb_for_graph (pp, bb);
@@ -443,9 +456,6 @@ redirect_edge_succ_nodup (edge e, basic_block new_succ)
     {
       s->flags |= e->flags;
       s->probability += e->probability;
-      if (s->probability > REG_BR_PROB_BASE)
-       s->probability = REG_BR_PROB_BASE;
-      s->count += e->count;
       /* FIXME: This should be called via a hook and only for IR_GIMPLE.  */
       redirect_edge_var_map_dup (s, e);
       remove_edge (e);
@@ -512,7 +522,6 @@ split_block_1 (basic_block bb, void *i)
     return NULL;
 
   new_bb->count = bb->count;
-  new_bb->frequency = bb->frequency;
   new_bb->discriminator = bb->discriminator;
 
   if (dom_info_available_p (CDI_DOMINATORS))
@@ -624,8 +633,7 @@ basic_block
 split_edge (edge e)
 {
   basic_block ret;
-  profile_count count = e->count;
-  int freq = EDGE_FREQUENCY (e);
+  profile_count count = e->count ();
   edge f;
   bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
   struct loop *loop;
@@ -639,9 +647,7 @@ split_edge (edge e)
 
   ret = cfg_hooks->split_edge (e);
   ret->count = count;
-  ret->frequency = freq;
-  single_succ_edge (ret)->probability = REG_BR_PROB_BASE;
-  single_succ_edge (ret)->count = count;
+  single_succ_edge (ret)->probability = profile_probability::always ();
 
   if (irr)
     {
@@ -869,8 +875,6 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
   fallthru = split_block_after_labels (bb);
   dummy = fallthru->src;
   dummy->count = profile_count::zero ();
-  dummy->frequency = 0;
-  fallthru->count = profile_count::zero ();
   bb = fallthru->dest;
 
   /* Redirect back edges we want to keep.  */
@@ -880,12 +884,7 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
 
       if (redirect_edge_p (e))
        {
-         dummy->frequency += EDGE_FREQUENCY (e);
-         if (dummy->frequency > BB_FREQ_MAX)
-           dummy->frequency = BB_FREQ_MAX;
-
-         dummy->count += e->count;
-         fallthru->count += e->count;
+         dummy->count += e->count ();
          ei_next (&ei);
          continue;
        }
@@ -1067,11 +1066,11 @@ can_duplicate_block_p (const_basic_block bb)
    AFTER.  */
 
 basic_block
-duplicate_block (basic_block bb, edge e, basic_block after)
+duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id)
 {
   edge s, n;
   basic_block new_bb;
-  profile_count new_count = e ? e->count : profile_count::uninitialized ();
+  profile_count new_count = e ? e->count (): profile_count::uninitialized ();
   edge_iterator ei;
 
   if (!cfg_hooks->duplicate_block)
@@ -1083,11 +1082,11 @@ duplicate_block (basic_block bb, edge e, basic_block after)
 
   gcc_checking_assert (can_duplicate_block_p (bb));
 
-  new_bb = cfg_hooks->duplicate_block (bb);
+  new_bb = cfg_hooks->duplicate_block (bb, id);
   if (after)
     move_block_after (new_bb, after);
 
-  new_bb->flags = bb->flags;
+  new_bb->flags = (bb->flags & ~BB_DUPLICATED);
   FOR_EACH_EDGE (s, ei, bb->succs)
     {
       /* Since we are creating edges from a new block to successors
@@ -1095,13 +1094,6 @@ duplicate_block (basic_block bb, edge e, basic_block after)
         is no need to actually check for duplicated edges.  */
       n = unchecked_make_edge (new_bb, s->dest, s->flags);
       n->probability = s->probability;
-      if (e && bb->count > profile_count::zero ())
-       {
-         n->count = s->count.apply_scale (new_count, bb->count);
-         s->count -= n->count;
-       }
-      else
-       n->count = s->count;
       n->aux = s->aux;
     }
 
@@ -1110,19 +1102,10 @@ duplicate_block (basic_block bb, edge e, basic_block after)
       new_bb->count = new_count;
       bb->count -= new_count;
 
-      new_bb->frequency = EDGE_FREQUENCY (e);
-      bb->frequency -= EDGE_FREQUENCY (e);
-
       redirect_edge_and_branch_force (e, new_bb);
-
-      if (bb->frequency < 0)
-       bb->frequency = 0;
     }
   else
-    {
-      new_bb->count = bb->count;
-      new_bb->frequency = bb->frequency;
-    }
+    new_bb->count = bb->count;
 
   set_bb_original (new_bb, bb);
   set_bb_copy (bb, new_bb);
@@ -1207,7 +1190,8 @@ flow_call_edges_add (sbitmap blocks)
 void
 execute_on_growing_pred (edge e)
 {
-  if (cfg_hooks->execute_on_growing_pred)
+  if (! (e->dest->flags & BB_DUPLICATED)
+      && cfg_hooks->execute_on_growing_pred)
     cfg_hooks->execute_on_growing_pred (e);
 }
 
@@ -1217,7 +1201,8 @@ execute_on_growing_pred (edge e)
 void
 execute_on_shrinking_pred (edge e)
 {
-  if (cfg_hooks->execute_on_shrinking_pred)
+  if (! (e->dest->flags & BB_DUPLICATED)
+      && cfg_hooks->execute_on_shrinking_pred)
     cfg_hooks->execute_on_shrinking_pred (e);
 }
 
@@ -1352,15 +1337,21 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
   unsigned i, j;
   basic_block bb, new_bb, dom_bb;
   edge e;
+  copy_bb_data id;
+
+  /* Mark the blocks to be copied.  This is used by edge creation hooks
+     to decide whether to reallocate PHI nodes capacity to avoid reallocating
+     PHIs in the set of source BBs.  */
+  for (i = 0; i < n; i++)
+    bbs[i]->flags |= BB_DUPLICATED;
 
   /* Duplicate bbs, update dominators, assign bbs to loops.  */
   for (i = 0; i < n; i++)
     {
       /* Duplicate.  */
       bb = bbs[i];
-      new_bb = new_bbs[i] = duplicate_block (bb, NULL, after);
+      new_bb = new_bbs[i] = duplicate_block (bb, NULL, after, &id);
       after = new_bb;
-      bb->flags |= BB_DUPLICATED;
       if (bb->loop_father)
        {
          /* Possibly set loop header.  */
@@ -1435,53 +1426,68 @@ split_block_before_cond_jump (basic_block bb)
 
 /* Work-horse for passes.c:check_profile_consistency.
    Do book-keeping of the CFG for the profile consistency checker.
-   If AFTER_PASS is 0, do pre-pass accounting, or if AFTER_PASS is 1
-   then do post-pass accounting.  Store the counting in RECORD.  */
+   Store the counting in RECORD.  */
 
 void
-account_profile_record (struct profile_record *record, int after_pass)
+profile_record_check_consistency (profile_record *record)
 {
   basic_block bb;
   edge_iterator ei;
   edge e;
-  int sum;
 
   FOR_ALL_BB_FN (bb, cfun)
    {
       if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
          && profile_status_for_fn (cfun) != PROFILE_ABSENT)
        {
-         sum = 0;
+         profile_probability sum = profile_probability::never ();
          FOR_EACH_EDGE (e, ei, bb->succs)
            sum += e->probability;
-         if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100)
-           record->num_mismatched_freq_out[after_pass]++;
+         if (EDGE_COUNT (bb->succs)
+             && sum.differs_from_p (profile_probability::always ()))
+           record->num_mismatched_freq_out++;
          profile_count lsum = profile_count::zero ();
          FOR_EACH_EDGE (e, ei, bb->succs)
-           lsum += e->count;
+           lsum += e->count ();
          if (EDGE_COUNT (bb->succs) && (lsum.differs_from_p (bb->count)))
-           record->num_mismatched_count_out[after_pass]++;
+           record->num_mismatched_count_out++;
        }
       if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
          && profile_status_for_fn (cfun) != PROFILE_ABSENT)
        {
-         sum = 0;
-         FOR_EACH_EDGE (e, ei, bb->preds)
-           sum += EDGE_FREQUENCY (e);
-         if (abs (sum - bb->frequency) > 100
-             || (MAX (sum, bb->frequency) > 10
-                 && abs ((sum - bb->frequency) * 100 / (MAX (sum, bb->frequency) + 1)) > 10))
-           record->num_mismatched_freq_in[after_pass]++;
+         profile_probability sum = profile_probability::never ();
          profile_count lsum = profile_count::zero ();
          FOR_EACH_EDGE (e, ei, bb->preds)
-           lsum += e->count;
+           {
+             sum += e->probability;
+             lsum += e->count ();
+           }
+         if (EDGE_COUNT (bb->preds)
+             && sum.differs_from_p (profile_probability::always ()))
+           record->num_mismatched_freq_in++;
          if (lsum.differs_from_p (bb->count))
-           record->num_mismatched_count_in[after_pass]++;
+           record->num_mismatched_count_in++;
        }
       if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
          || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
        continue;
       gcc_assert (cfg_hooks->account_profile_record);
-      cfg_hooks->account_profile_record (bb, after_pass, record);
+      cfg_hooks->account_profile_record (bb, record);
+   }
+}
+
+/* Work-horse for passes.c:acount_profile.
+   Do book-keeping of the CFG for the profile accounting.
+   Store the counting in RECORD.  */
+
+void
+profile_record_account_profile (profile_record *record)
+{
+  basic_block bb;
+
+  FOR_ALL_BB_FN (bb, cfun)
+   {
+      gcc_assert (cfg_hooks->account_profile_record);
+      cfg_hooks->account_profile_record (bb, record);
    }
 }