diff gcc/ipa-profile.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/ipa-profile.c	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/ipa-profile.c	Thu Oct 25 07:37:49 2018 +0900
@@ -1,5 +1,5 @@
 /* Basic IPA optimizations based on profile.
-   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   Copyright (C) 2003-2018 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -25,13 +25,6 @@
      from profile feedback. This histogram is complete only with LTO,
      otherwise it contains information only about the current unit.
 
-     Similar histogram is also estimated by coverage runtime.  This histogram
-     is not dependent on LTO, but it suffers from various defects; first
-     gcov runtime is not weighting individual basic block by estimated execution
-     time and second the merging of multiple runs makes assumption that the
-     histogram distribution did not change.  Consequentely histogram constructed
-     here may be more precise.
-
      The information is used to set hot/cold thresholds.
    - Next speculative indirect call resolution is performed:  the local
      profile pass assigns profile-id to each function and provide us with a
@@ -179,53 +172,54 @@
   hash_table<histogram_hash> hashtable (10);
   
   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
-    FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
-      {
-	int time = 0;
-	int size = 0;
-        for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-	  {
-	    gimple *stmt = gsi_stmt (gsi);
-	    if (gimple_code (stmt) == GIMPLE_CALL
-		&& !gimple_call_fndecl (stmt))
-	      {
-		histogram_value h;
-		h = gimple_histogram_value_of_type
-		      (DECL_STRUCT_FUNCTION (node->decl),
-		       stmt, HIST_TYPE_INDIR_CALL);
-		/* No need to do sanity check: gimple_ic_transform already
-		   takes away bad histograms.  */
-		if (h)
-		  {
-		    /* counter 0 is target, counter 1 is number of execution we called target,
-		       counter 2 is total number of executions.  */
-		    if (h->hvalue.counters[2])
-		      {
-			struct cgraph_edge * e = node->get_edge (stmt);
-			if (e && !e->indirect_unknown_callee)
-			  continue;
-			e->indirect_info->common_target_id
-			  = h->hvalue.counters [0];
-			e->indirect_info->common_target_probability
-			  = GCOV_COMPUTE_SCALE (h->hvalue.counters [1], h->hvalue.counters [2]);
-			if (e->indirect_info->common_target_probability > REG_BR_PROB_BASE)
-			  {
-			    if (dump_file)
-			      fprintf (dump_file, "Probability capped to 1\n");
-			    e->indirect_info->common_target_probability = REG_BR_PROB_BASE;
-			  }
-		      }
-		    gimple_remove_histogram_value (DECL_STRUCT_FUNCTION (node->decl),
-						    stmt, h);
-		  }
-	      }
-	    time += estimate_num_insns (stmt, &eni_time_weights);
-	    size += estimate_num_insns (stmt, &eni_size_weights);
-	  }
-	if (bb->count.initialized_p ())
-	  account_time_size (&hashtable, histogram, bb->count.to_gcov_type (),
-			     time, size);
-      }
+    if (ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (node->decl))->count.ipa_p ())
+      FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
+	{
+	  int time = 0;
+	  int size = 0;
+	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+	    {
+	      gimple *stmt = gsi_stmt (gsi);
+	      if (gimple_code (stmt) == GIMPLE_CALL
+		  && !gimple_call_fndecl (stmt))
+		{
+		  histogram_value h;
+		  h = gimple_histogram_value_of_type
+			(DECL_STRUCT_FUNCTION (node->decl),
+			 stmt, HIST_TYPE_INDIR_CALL);
+		  /* No need to do sanity check: gimple_ic_transform already
+		     takes away bad histograms.  */
+		  if (h)
+		    {
+		      /* counter 0 is target, counter 1 is number of execution we called target,
+			 counter 2 is total number of executions.  */
+		      if (h->hvalue.counters[2])
+			{
+			  struct cgraph_edge * e = node->get_edge (stmt);
+			  if (e && !e->indirect_unknown_callee)
+			    continue;
+			  e->indirect_info->common_target_id
+			    = h->hvalue.counters [0];
+			  e->indirect_info->common_target_probability
+			    = GCOV_COMPUTE_SCALE (h->hvalue.counters [1], h->hvalue.counters [2]);
+			  if (e->indirect_info->common_target_probability > REG_BR_PROB_BASE)
+			    {
+			      if (dump_file)
+				fprintf (dump_file, "Probability capped to 1\n");
+			      e->indirect_info->common_target_probability = REG_BR_PROB_BASE;
+			    }
+			}
+		      gimple_remove_histogram_value (DECL_STRUCT_FUNCTION (node->decl),
+						      stmt, h);
+		    }
+		}
+	      time += estimate_num_insns (stmt, &eni_time_weights);
+	      size += estimate_num_insns (stmt, &eni_size_weights);
+	    }
+	  if (bb->count.ipa_p () && bb->count.initialized_p ())
+	    account_time_size (&hashtable, histogram, bb->count.ipa ().to_gcov_type (),
+			       time, size);
+	}
   histogram.qsort (cmp_counts);
 }
 
@@ -330,33 +324,34 @@
 	 it is executed by the train run.  Transfer the function only if all
 	 callers are unlikely executed.  */
       if (profile_info
-	  && edge->callee->count.initialized_p ()
-	  /* Thunks are not profiled.  This is more or less implementation
-	     bug.  */
-	  && !d->function_symbol->thunk.thunk_p
+	  && !(edge->callee->count.ipa () == profile_count::zero ())
 	  && (edge->caller->frequency != NODE_FREQUENCY_UNLIKELY_EXECUTED
 	      || (edge->caller->global.inlined_to
 		  && edge->caller->global.inlined_to->frequency
 		     != NODE_FREQUENCY_UNLIKELY_EXECUTED)))
 	  d->maybe_unlikely_executed = false;
-      if (!edge->frequency)
+      if (edge->count.ipa ().initialized_p ()
+	  && !edge->count.ipa ().nonzero_p ())
 	continue;
       switch (edge->caller->frequency)
         {
 	case NODE_FREQUENCY_UNLIKELY_EXECUTED:
 	  break;
 	case NODE_FREQUENCY_EXECUTED_ONCE:
-	  if (dump_file && (dump_flags & TDF_DETAILS))
-	    fprintf (dump_file, "  Called by %s that is executed once\n",
-		     edge->caller->name ());
-	  d->maybe_unlikely_executed = false;
-	  if (ipa_call_summaries->get (edge)->loop_depth)
-	    {
-	      d->maybe_executed_once = false;
-	      if (dump_file && (dump_flags & TDF_DETAILS))
-	        fprintf (dump_file, "  Called in loop\n");
-	    }
-	  break;
+	  {
+	    if (dump_file && (dump_flags & TDF_DETAILS))
+	      fprintf (dump_file, "  Called by %s that is executed once\n",
+		       edge->caller->name ());
+	    d->maybe_unlikely_executed = false;
+	    ipa_call_summary *s = ipa_call_summaries->get (edge);
+	    if (s != NULL && s->loop_depth)
+	      {
+		d->maybe_executed_once = false;
+		if (dump_file && (dump_flags & TDF_DETAILS))
+		  fprintf (dump_file, "  Called in loop\n");
+	      }
+	    break;
+	  }
 	case NODE_FREQUENCY_HOT:
 	case NODE_FREQUENCY_NORMAL:
 	  if (dump_file && (dump_flags & TDF_DETAILS))
@@ -430,11 +425,11 @@
     }
 
   /* With profile we can decide on hot/normal based on count.  */
-  if (node->count.initialized_p ())
+  if (node->count. ipa().initialized_p ())
     {
       bool hot = false;
-      if (!(node->count == profile_count::zero ())
-	  && node->count >= get_hot_bb_threshold ())
+      if (!(node->count. ipa() == profile_count::zero ())
+	  && node->count. ipa() >= get_hot_bb_threshold ())
 	hot = true;
       if (!hot)
 	hot |= contains_hot_call_p (node);
@@ -510,25 +505,7 @@
       gcov_type threshold;
 
       gcc_assert (overall_size);
-      if (dump_file)
-	{
-	  gcov_type min, cumulated_time = 0, cumulated_size = 0;
 
-	  fprintf (dump_file, "Overall time: %" PRId64"\n",
-		   (int64_t)overall_time);
-	  min = get_hot_bb_threshold ();
-          for (i = 0; i < (int)histogram.length () && histogram[i]->count >= min;
-	       i++)
-	    {
-	      cumulated_time += histogram[i]->count * histogram[i]->time;
-	      cumulated_size += histogram[i]->size;
-	    }
-	  fprintf (dump_file, "GCOV min count: %" PRId64
-		   " Time:%3.2f%% Size:%3.2f%%\n", 
-		   (int64_t)min,
-		   cumulated_time * 100.0 / overall_time,
-		   cumulated_size * 100.0 / overall_size);
-	}
       cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;
       threshold = 0;
       for (i = 0; cumulated < cutoff; i++)
@@ -555,6 +532,7 @@
 		   cumulated_time * 100.0 / overall_time,
 		   cumulated_size * 100.0 / overall_size);
 	}
+
       if (threshold > get_hot_bb_threshold ()
 	  || in_lto_p)
 	{
@@ -666,9 +644,7 @@
 		      e->make_speculative
 			(n2,
 			 e->count.apply_probability
-				     (e->indirect_info->common_target_probability),
-			 apply_scale (e->frequency,
-				      e->indirect_info->common_target_probability));
+				     (e->indirect_info->common_target_probability));
 		      update = true;
 		    }
 		}