Bug 521435 Apply a patch to gcc to fix the LTO+PGO build
MozReview-Commit-ID: JIytYLHEuJH
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