diff gcc/lto-cgraph.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/lto-cgraph.c	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/lto-cgraph.c	Thu Oct 25 07:37:49 2018 +0900
@@ -1,7 +1,7 @@
 /* Write and read the cgraph to the memory mapped representation of a
    .o file.
 
-   Copyright (C) 2009-2017 Free Software Foundation, Inc.
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
 
 This file is part of GCC.
@@ -37,7 +37,6 @@
 #include "pass_manager.h"
 #include "ipa-utils.h"
 #include "omp-offload.h"
-#include "ipa-chkp.h"
 #include "stringpool.h"
 #include "attribs.h"
 
@@ -266,7 +265,6 @@
   bp_pack_enum (&bp, cgraph_inline_failed_t,
 	        CIF_N_REASONS, edge->inline_failed);
   bp_pack_var_len_unsigned (&bp, uid);
-  bp_pack_var_len_unsigned (&bp, edge->frequency);
   bp_pack_value (&bp, edge->indirect_inlining_edge, 1);
   bp_pack_value (&bp, edge->speculative, 1);
   bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1);
@@ -541,8 +539,10 @@
   bp_pack_value (&bp, node->thunk.thunk_p, 1);
   bp_pack_value (&bp, node->parallelized_function, 1);
   bp_pack_enum (&bp, ld_plugin_symbol_resolution,
-	        LDPR_NUM_KNOWN, node->resolution);
-  bp_pack_value (&bp, node->instrumentation_clone, 1);
+	        LDPR_NUM_KNOWN,
+		/* When doing incremental link, we will get new resolution
+		   info next time we process the file.  */
+		flag_incremental_link ? LDPR_UNKNOWN : node->resolution);
   bp_pack_value (&bp, node->split_part, 1);
   streamer_write_bitpack (&bp);
   streamer_write_data_stream (ob->main_stream, section, strlen (section) + 1);
@@ -556,15 +556,13 @@
 	  + (node->thunk.add_pointer_bounds_args != 0) * 8);
       streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
       streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value);
+      streamer_write_uhwi_stream (ob->main_stream, node->thunk.indirect_offset);
     }
   streamer_write_hwi_stream (ob->main_stream, node->profile_id);
   if (DECL_STATIC_CONSTRUCTOR (node->decl))
     streamer_write_hwi_stream (ob->main_stream, node->get_init_priority ());
   if (DECL_STATIC_DESTRUCTOR (node->decl))
     streamer_write_hwi_stream (ob->main_stream, node->get_fini_priority ());
-
-  if (node->instrumentation_clone)
-    lto_output_fn_decl_index (ob->decl_state, ob->main_stream, node->orig_decl);
 }
 
 /* Output the varpool NODE to OB. 
@@ -696,39 +694,14 @@
 static void
 output_profile_summary (struct lto_simple_output_block *ob)
 {
-  unsigned h_ix;
-  struct bitpack_d bp;
-
   if (profile_info)
     {
       /* We do not output num and run_max, they are not used by
          GCC profile feedback and they are difficult to merge from multiple
          units.  */
-      gcc_assert (profile_info->runs);
-      streamer_write_uhwi_stream (ob->main_stream, profile_info->runs);
-      streamer_write_gcov_count_stream (ob->main_stream, profile_info->sum_max);
-
-      /* sum_all is needed for computing the working set with the
-         histogram.  */
-      streamer_write_gcov_count_stream (ob->main_stream, profile_info->sum_all);
+      unsigned runs = (profile_info->runs);
+      streamer_write_uhwi_stream (ob->main_stream, runs);
 
-      /* Create and output a bitpack of non-zero histogram entries indices.  */
-      bp = bitpack_create (ob->main_stream);
-      for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
-        bp_pack_value (&bp, profile_info->histogram[h_ix].num_counters > 0, 1);
-      streamer_write_bitpack (&bp);
-      /* Now stream out only those non-zero entries.  */
-      for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
-        {
-          if (!profile_info->histogram[h_ix].num_counters)
-            continue;
-          streamer_write_gcov_count_stream (ob->main_stream,
-                                      profile_info->histogram[h_ix].num_counters);
-          streamer_write_gcov_count_stream (ob->main_stream,
-                                      profile_info->histogram[h_ix].min_value);
-          streamer_write_gcov_count_stream (ob->main_stream,
-                                      profile_info->histogram[h_ix].cum_value);
-         }
       /* IPA-profile computes hot bb threshold based on cumulated
 	 whole program profile.  We need to stream it down to ltrans.  */
        if (flag_wpa)
@@ -773,33 +746,11 @@
     {
       symtab_node *node = lto_symtab_encoder_deref (encoder, i);
 
-      /* IPA_REF_ALIAS and IPA_REF_CHKP references are always preserved
+      /* IPA_REF_ALIAS references are always preserved
 	 in the boundary.  Alias node can't have other references and
 	 can be always handled as if it's not in the boundary.  */
       if (!node->alias && !lto_symtab_encoder_in_partition_p (encoder, node))
-	{
-	  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
-	  /* Output IPA_REF_CHKP reference.  */
-	  if (cnode
-	      && cnode->instrumented_version
-	      && !cnode->instrumentation_clone)
-	    {
-	      for (int i = 0; node->iterate_reference (i, ref); i++)
-		if (ref->use == IPA_REF_CHKP)
-		  {
-		    if (lto_symtab_encoder_lookup (encoder, ref->referred)
-			!= LCC_NOT_FOUND)
-		      {
-			int nref = lto_symtab_encoder_lookup (encoder, node);
-			streamer_write_gcov_count_stream (ob->main_stream, 1);
-			streamer_write_uhwi_stream (ob->main_stream, nref);
-			lto_output_ref (ob, ref, encoder);
-		      }
-		    break;
-		  }
-	    }
-	  continue;
-	}
+	continue;
 
       count = node->ref_list.nreferences ();
       if (count)
@@ -911,8 +862,7 @@
 	      && (((vnode->ctor_useable_for_folding_p ()
 		   && (!DECL_VIRTUAL_P (vnode->decl)
 		       || !flag_wpa
-		       || flag_ltrans_devirtualize))
-		  || POINTER_BOUNDS_P (vnode->decl))))
+		       || flag_ltrans_devirtualize)))))
 	    {
 	      lto_set_symtab_encoder_encode_initializer (encoder, vnode);
 	      create_references (encoder, vnode);
@@ -1202,7 +1152,6 @@
   node->parallelized_function = bp_unpack_value (bp, 1);
   node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution,
 				     LDPR_NUM_KNOWN);
-  node->instrumentation_clone = bp_unpack_value (bp, 1);
   node->split_part = bp_unpack_value (bp, 1);
   gcc_assert (flag_ltrans
 	      || (!node->in_other_partition
@@ -1248,7 +1197,7 @@
   if (clone_ref != LCC_NOT_FOUND)
     {
       node = dyn_cast<cgraph_node *> (nodes[clone_ref])->create_clone (fn_decl,
-	profile_count::uninitialized (), CGRAPH_FREQ_BASE, false,
+	profile_count::uninitialized (), false,
 	vNULL, false, NULL, NULL);
     }
   else
@@ -1258,6 +1207,8 @@
 	 of ipa passes is done.  Alays forcingly create a fresh node.  */
       node = symtab->create_empty ();
       node->decl = fn_decl;
+      if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
+	node->ifunc_resolver = 1;
       node->register_symbol ();
     }
 
@@ -1291,9 +1242,9 @@
      have already been read will have their tag stored in the 'aux'
      field.  Since built-in functions can be referenced in multiple
      functions, they are expected to be read more than once.  */
-  if (node->aux && !DECL_BUILT_IN (node->decl))
+  if (node->aux && !fndecl_built_in_p (node->decl))
     internal_error ("bytecode stream: found multiple instances of cgraph "
-		    "node with uid %d", node->uid);
+		    "node with uid %d", node->get_uid ());
 
   node->tp_first_run = streamer_read_uhwi (ib);
 
@@ -1321,10 +1272,12 @@
       int type = streamer_read_uhwi (ib);
       HOST_WIDE_INT fixed_offset = streamer_read_uhwi (ib);
       HOST_WIDE_INT virtual_value = streamer_read_uhwi (ib);
+      HOST_WIDE_INT indirect_offset = streamer_read_uhwi (ib);
 
       node->thunk.fixed_offset = fixed_offset;
+      node->thunk.virtual_value = virtual_value;
+      node->thunk.indirect_offset = indirect_offset;
       node->thunk.this_adjusting = (type & 2);
-      node->thunk.virtual_value = virtual_value;
       node->thunk.virtual_offset_p = (type & 4);
       node->thunk.add_pointer_bounds_args = (type & 8);
     }
@@ -1336,13 +1289,6 @@
   if (DECL_STATIC_DESTRUCTOR (node->decl))
     node->set_fini_priority (streamer_read_hwi (ib));
 
-  if (node->instrumentation_clone)
-    {
-      decl_index = streamer_read_uhwi (ib);
-      fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index);
-      node->orig_decl = fn_decl;
-    }
-
   return node;
 }
 
@@ -1464,7 +1410,6 @@
   struct cgraph_edge *edge;
   unsigned int stmt_id;
   profile_count count;
-  int freq;
   cgraph_inline_failed_t inline_failed;
   struct bitpack_d bp;
   int ecf_flags = 0;
@@ -1487,12 +1432,11 @@
   bp = streamer_read_bitpack (ib);
   inline_failed = bp_unpack_enum (&bp, cgraph_inline_failed_t, CIF_N_REASONS);
   stmt_id = bp_unpack_var_len_unsigned (&bp);
-  freq = (int) bp_unpack_var_len_unsigned (&bp);
 
   if (indirect)
-    edge = caller->create_indirect_edge (NULL, 0, count, freq);
+    edge = caller->create_indirect_edge (NULL, 0, count);
   else
-    edge = caller->create_edge (callee, NULL, count, freq);
+    edge = caller->create_edge (callee, NULL, count);
 
   edge->indirect_inlining_edge = bp_unpack_value (&bp, 1);
   edge->speculative = bp_unpack_value (&bp, 1);
@@ -1586,35 +1530,6 @@
 	      = dyn_cast<cgraph_node *> (nodes[ref]);
 	  else
 	    cnode->global.inlined_to = NULL;
-
-	  /* Compute instrumented_version.  */
-	  if (cnode->instrumentation_clone)
-	    {
-	      gcc_assert (cnode->orig_decl);
-
-	      cnode->instrumented_version = cgraph_node::get (cnode->orig_decl);
-	      if (cnode->instrumented_version)
-		{
-		  /* We may have multiple nodes for a single function which
-		     will be merged later.  To have a proper merge we need
-		     to keep instrumentation_version reference between nodes
-		     consistent: each instrumented_version reference should
-		     have proper reverse reference.  Thus don't break existing
-		     instrumented_version reference if it already exists.  */
-		  if (cnode->instrumented_version->instrumented_version)
-		    cnode->instrumented_version = NULL;
-		  else
-		    cnode->instrumented_version->instrumented_version = cnode;
-		}
-
-	      /* Restore decl names reference except for wrapper functions.  */
-	      if (!chkp_wrap_function (cnode->orig_decl))
-		{
-		  tree name = DECL_ASSEMBLER_NAME (cnode->decl);
-		  IDENTIFIER_TRANSPARENT_ALIAS (name) = 1;
-		  TREE_CHAIN (name) = DECL_ASSEMBLER_NAME (cnode->orig_decl);
-		}
-	    }
 	}
 
       ref = (int) (intptr_t) node->same_comdat_group;
@@ -1654,46 +1569,16 @@
     }
 }
 	    
-
-static struct gcov_ctr_summary lto_gcov_summary;
-
 /* Input profile_info from IB.  */
 static void
 input_profile_summary (struct lto_input_block *ib,
 		       struct lto_file_decl_data *file_data)
 {
-  unsigned h_ix;
-  struct bitpack_d bp;
   unsigned int runs = streamer_read_uhwi (ib);
   if (runs)
     {
       file_data->profile_info.runs = runs;
-      file_data->profile_info.sum_max = streamer_read_gcov_count (ib);
-      file_data->profile_info.sum_all = streamer_read_gcov_count (ib);
 
-      memset (file_data->profile_info.histogram, 0,
-              sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
-      /* Input the bitpack of non-zero histogram indices.  */
-      bp = streamer_read_bitpack (ib);
-      /* Read in and unpack the full bitpack, flagging non-zero
-         histogram entries by setting the num_counters non-zero.  */
-      for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
-        {
-          file_data->profile_info.histogram[h_ix].num_counters
-              = bp_unpack_value (&bp, 1);
-        }
-      for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
-        {
-          if (!file_data->profile_info.histogram[h_ix].num_counters)
-            continue;
-
-          file_data->profile_info.histogram[h_ix].num_counters
-              = streamer_read_gcov_count (ib);
-          file_data->profile_info.histogram[h_ix].min_value
-              = streamer_read_gcov_count (ib);
-          file_data->profile_info.histogram[h_ix].cum_value
-              = streamer_read_gcov_count (ib);
-        }
       /* IPA-profile computes hot bb threshold based on cumulated
 	 whole program profile.  We need to stream it down to ltrans.  */
       if (flag_ltrans)
@@ -1708,13 +1593,10 @@
 merge_profile_summaries (struct lto_file_decl_data **file_data_vec)
 {
   struct lto_file_decl_data *file_data;
-  unsigned int j, h_ix;
+  unsigned int j;
   gcov_unsigned_t max_runs = 0;
   struct cgraph_node *node;
   struct cgraph_edge *edge;
-  gcov_type saved_sum_all = 0;
-  gcov_ctr_summary *saved_profile_info = 0;
-  int saved_scale = 0;
 
   /* Find unit with maximal number of runs.  If we ever get serious about
      roundoff errors, we might also consider computing smallest common
@@ -1735,70 +1617,8 @@
       return;
     }
 
-  profile_info = &lto_gcov_summary;
-  lto_gcov_summary.runs = max_runs;
-  lto_gcov_summary.sum_max = 0;
-  memset (lto_gcov_summary.histogram, 0,
-          sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
-
-  /* Rescale all units to the maximal number of runs.
-     sum_max can not be easily merged, as we have no idea what files come from
-     the same run.  We do not use the info anyway, so leave it 0.  */
-  for (j = 0; (file_data = file_data_vec[j]) != NULL; j++)
-    if (file_data->profile_info.runs)
-      {
-	int scale = GCOV_COMPUTE_SCALE (max_runs,
-                                        file_data->profile_info.runs);
-	lto_gcov_summary.sum_max
-            = MAX (lto_gcov_summary.sum_max,
-                   apply_scale (file_data->profile_info.sum_max, scale));
-	lto_gcov_summary.sum_all
-            = MAX (lto_gcov_summary.sum_all,
-                   apply_scale (file_data->profile_info.sum_all, scale));
-        /* Save a pointer to the profile_info with the largest
-           scaled sum_all and the scale for use in merging the
-           histogram.  */
-        if (!saved_profile_info
-            || lto_gcov_summary.sum_all > saved_sum_all)
-          {
-            saved_profile_info = &file_data->profile_info;
-            saved_sum_all = lto_gcov_summary.sum_all;
-            saved_scale = scale;
-          }
-      }
-
-  gcc_assert (saved_profile_info);
-
-  /* Scale up the histogram from the profile that had the largest
-     scaled sum_all above.  */
-  for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
-    {
-      /* Scale up the min value as we did the corresponding sum_all
-         above. Use that to find the new histogram index.  */
-      gcov_type scaled_min
-          = apply_scale (saved_profile_info->histogram[h_ix].min_value,
-                         saved_scale);
-      /* The new index may be shared with another scaled histogram entry,
-         so we need to account for a non-zero histogram entry at new_ix.  */
-      unsigned new_ix = gcov_histo_index (scaled_min);
-      lto_gcov_summary.histogram[new_ix].min_value
-          = (lto_gcov_summary.histogram[new_ix].num_counters
-             ? MIN (lto_gcov_summary.histogram[new_ix].min_value, scaled_min)
-             : scaled_min);
-      /* Some of the scaled counter values would ostensibly need to be placed
-         into different (larger) histogram buckets, but we keep things simple
-         here and place the scaled cumulative counter value in the bucket
-         corresponding to the scaled minimum counter value.  */
-      lto_gcov_summary.histogram[new_ix].cum_value
-          += apply_scale (saved_profile_info->histogram[h_ix].cum_value,
-                          saved_scale);
-      lto_gcov_summary.histogram[new_ix].num_counters
-          += saved_profile_info->histogram[h_ix].num_counters;
-    }
-
-  /* Watch roundoff errors.  */
-  if (lto_gcov_summary.sum_max < max_runs)
-    lto_gcov_summary.sum_max = max_runs;
+  profile_info = XCNEW (gcov_summary);
+  profile_info->runs = max_runs;
 
   /* If merging already happent at WPA time, we are done.  */
   if (flag_ltrans)
@@ -1823,8 +1643,13 @@
 	if (scale == REG_BR_PROB_BASE)
 	  continue;
 	for (edge = node->callees; edge; edge = edge->next_callee)
-	  edge->count = edge->count.apply_scale (scale, REG_BR_PROB_BASE);
-	node->count = node->count.apply_scale (scale, REG_BR_PROB_BASE);
+	  if (edge->count.ipa ().nonzero_p ())
+	    edge->count = edge->count.apply_scale (scale, REG_BR_PROB_BASE);
+	for (edge = node->indirect_calls; edge; edge = edge->next_callee)
+	  if (edge->count.ipa ().nonzero_p ())
+	    edge->count = edge->count.apply_scale (scale, REG_BR_PROB_BASE);
+	if (node->count.ipa ().nonzero_p ())
+	  node->count = node->count.apply_scale (scale, REG_BR_PROB_BASE);
       }
 }
 
@@ -1872,10 +1697,6 @@
 
   merge_profile_summaries (file_data_vec);
 
-  if (!flag_auto_profile)
-    get_working_sets ();
-
-
   /* Clear out the aux field that was used to store enough state to
      tell which nodes should be overwritten.  */
   FOR_EACH_FUNCTION (node)
@@ -1956,7 +1777,7 @@
 static int
 output_cgraph_opt_summary_p (struct cgraph_node *node)
 {
-  return (node->clone_of
+  return ((node->clone_of || node->former_clone_of)
 	  && (node->clone.tree_map
 	      || node->clone.args_to_skip
 	      || node->clone.combined_args_to_skip));