Bug 521435 Apply a patch to gcc to fix the LTO+PGO build draft
authorTom Ritter <tom@mozilla.com>
Sat, 03 Mar 2018 13:58:17 -0600
changeset 763019 4faffe83f2bcaf153530d374c8938d0ee10bfd43
parent 762516 bddc2ca6492179e4b287c3c05f249bba1350e8ef
child 763020 63b54490d9ed251a2eda0e53ecb960eb7e1d15a0
push id101309
push userbmo:tom@mozilla.com
push dateMon, 05 Mar 2018 00:57:59 +0000
bugs521435
milestone60.0a1
Bug 521435 Apply a patch to gcc to fix the LTO+PGO build MozReview-Commit-ID: JIytYLHEuJH
build/unix/build-gcc/lto.patch
taskcluster/scripts/misc/build-gcc-6-linux.sh
new file mode 100644
--- /dev/null
+++ b/build/unix/build-gcc/lto.patch
@@ -0,0 +1,115 @@
+Index: a/gcc/ipa-cp.c
+===================================================================
+--- a/gcc/ipa-cp.c	(revision 257881)
++++ a/gcc/ipa-cp.c	(working copy)
+@@ -544,6 +544,24 @@ determine_versionability (struct cgraph_
+       reason = "calls comdat-local function";
+     }
+ 
++  /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
++     works only when inlined.  Cloning them may still lead to better code
++     becuase ipa-cp will not give up on cloning further.  If the function is
++     external this however leads to wrong code becuase we may end up producing
++     offline copy of the function.  */
++  if (DECL_EXTERNAL (node->decl))
++    for (cgraph_edge *edge = node->callees; !reason && edge;
++	 edge = edge->next_callee)
++      if (DECL_BUILT_IN (edge->callee->decl)
++	  && DECL_BUILT_IN_CLASS (edge->callee->decl) == BUILT_IN_NORMAL)
++        {
++	  if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
++	    reason = "external function which calls va_arg_pack";
++	  if (DECL_FUNCTION_CODE (edge->callee->decl)
++	      == BUILT_IN_VA_ARG_PACK_LEN)
++	    reason = "external function which calls va_arg_pack_len";
++        }
++
+   if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
+     fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
+ 	     node->name (), node->order, reason);
+Index: a/gcc/ipa-utils.c
+===================================================================
+--- a/gcc/ipa-utils.c	(revision 257881)
++++ a/gcc/ipa-utils.c	(working copy)
+@@ -403,6 +403,8 @@ ipa_merge_profiles (struct cgraph_node *
+ 
+   if (!dst->count)
+     return;
++  if (!src->count || src->alias)
++    return;
+   if (symtab->dump_file)
+     {
+       fprintf (symtab->dump_file, "Merging profiles of %s/%i to %s/%i\n",
+Index: a/gcc/lto/lto-partition.c
+===================================================================
+--- a/gcc/lto/lto-partition.c	(revision 257881)
++++ a/gcc/lto/lto-partition.c	(working copy)
+@@ -751,7 +751,8 @@ lto_balanced_map (int n_lto_partitions)
+ 	  if (npartitions < n_lto_partitions)
+ 	    partition_size = total_size / (n_lto_partitions - npartitions);
+ 	  else
+-	    partition_size = INT_MAX;
++	    /* Watch for overflow.  */
++	    partition_size = INT_MAX / 16;
+ 
+ 	  if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))
+ 	    partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);
+Index: a/gcc/lto/lto.c
+===================================================================
+--- a/gcc/lto/lto.c	(revision 257881)
++++ a/gcc/lto/lto.c	(working copy)
+@@ -1611,7 +1611,20 @@ unify_scc (struct data_in *data_in, unsi
+ 	  /* Fixup the streamer cache with the prevailing nodes according
+ 	     to the tree node mapping computed by compare_tree_sccs.  */
+ 	  if (len == 1)
+-	    streamer_tree_cache_replace_tree (cache, pscc->entries[0], from);
++	    {
++	      if (!flag_ltrans)
++		{
++		  tree t = pscc->entries[0];
++		  /* Register variables and functions with the
++		     symbol table.  */
++		  if (TREE_CODE (t) == VAR_DECL)
++		    lto_register_var_decl_in_symtab (data_in, t, from);
++		  else if (TREE_CODE (t) == FUNCTION_DECL
++			   && !DECL_BUILT_IN (t))
++		    lto_register_function_decl_in_symtab (data_in, t, from);
++		 }
++	       streamer_tree_cache_replace_tree (cache, pscc->entries[0], from);
++	    }
+ 	  else
+ 	    {
+ 	      tree *map2 = XALLOCAVEC (tree, 2 * len);
+@@ -1619,6 +1632,18 @@ unify_scc (struct data_in *data_in, unsi
+ 		{
+ 		  map2[i*2] = (tree)(uintptr_t)(from + i);
+ 		  map2[i*2+1] = scc->entries[i];
++		  if (!flag_ltrans)
++		    {
++		      tree t = scc->entries[i];
++		      /* Register variables and functions with the
++			 symbol table.  */
++		      if (TREE_CODE (t) == VAR_DECL)
++			lto_register_var_decl_in_symtab (data_in, t, from + i);
++		      else if (TREE_CODE (t) == FUNCTION_DECL
++			       && !DECL_BUILT_IN (t))
++			lto_register_function_decl_in_symtab
++				 (data_in, t, from + i);
++		     }
+ 		}
+ 	      qsort (map2, len, 2 * sizeof (tree), cmp_tree);
+ 	      qsort (map, len, 2 * sizeof (tree), cmp_tree);
+@@ -2867,7 +2892,12 @@ read_cgraph_and_symbols (unsigned nfiles
+ 	&& snode->lto_file_data
+ 	&& snode->lto_file_data->resolution_map
+ 	&& (res = snode->lto_file_data->resolution_map->get (snode->decl)))
+-      snode->resolution = *res;
++      {
++	if (*res == LDPR_UNKNOWN)
++	  fatal_error (input_location, "missing resolution data for %s",
++		       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (snode->decl)));
++        snode->resolution = *res;
++      }
+   for (i = 0; all_file_decl_data[i]; i++)
+     if (all_file_decl_data[i]->resolution_map)
+       {
--- a/taskcluster/scripts/misc/build-gcc-6-linux.sh
+++ b/taskcluster/scripts/misc/build-gcc-6-linux.sh
@@ -33,14 +33,15 @@ b5b14added7d78a8d1ca70b5cb75fef57ce21972
 850bf21eafdfe5cd5f6827148184c08c4a0852a37ccf36ce69855334d2c914d4  gcc-6.4.0.tar.xz
 752079520b4690531171d0f4532e40f08600215feefede70b24fabdc6f1ab160  gmp-5.1.3.tar.bz2
 8ceebbf4d9a81afa2b4449113cee4b7cb14a687d7a549a963deb5e2a41458b6b  isl-0.15.tar.bz2
 ae79f8d41d8a86456b68607e9ca398d00f8b7342d1d83bcf4428178ac45380c7  mpc-0.8.2.tar.gz
 ca498c1c7a74dd37a576f353312d1e68d490978de4395fa28f1cbd46a364e658  mpfr-3.1.5.tar.bz2
 EOF
 
 prepare
+apply_patch $data_dir/lto.patch
 build_binutils
 build_gcc
 
 # Put a tarball in the artifacts dir
 mkdir -p $UPLOAD_DIR
 cp $HOME_DIR/gcc.tar.* $UPLOAD_DIR