This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, 4.9/4.10] Profile based option tuning
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Pengfei Yuan <0xcoolypf at gmail dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 22 Jul 2014 15:39:20 +0200
- Subject: Re: [PATCH, 4.9/4.10] Profile based option tuning
- Authentication-results: sourceware.org; auth=none
- References: <CACmZjJL=PPKMuCspMPfS82zud_rgshLM7VLzbMMkTQNs2DbupA at mail dot gmail dot com>
On Mon, Jul 21, 2014 at 7:13 AM, Pengfei Yuan <0xcoolypf@gmail.com> wrote:
> Hi,
>
> This patch tunes optimization options based on profile data:
> * Disable PGO options if profile is not available or empty.
> * Optimize for size if profile is available but empty.
Err ... these don't seem interesting cases to "optimize" for?
Richard.
> Here is an experiment on Firefox PGO build:
>
> CPU Intel Core i7-4770
> RAM 32 GB
> OS Debian sid amd64
> Firefox source mozilla-central, changeset 4bafe35cfb65
> Compiler GCC 4.9.2 20140721 (prerelease)
>
> Result:
>
> Size of libxul.so | Octane benchmark score
> PGO w/o this patch 67206232 32440.4 +/- 0.35%
> PGO w/ this patch 66604312 32765.8 +/- 0.56%
>
> With this patch, the size of PGO-built libxul.so decreases by 0.9% and the
> performance improves slightly.
>
> Regards,
>
> Yuan Pengfei
> Peking University
>
>
> gcc/ChangeLog:
>
> * coverage.c (coverage_check): New function.
> * coverage.h (coverage_check): New function.
> * toplev.c (profile_based_option_override): New function.
> (process_options): Add profile based option tuning.
>
>
> diff --git a/gcc/coverage.c b/gcc/coverage.c
> index 4c06fa4..205bee5 100644
> --- a/gcc/coverage.c
> +++ b/gcc/coverage.c
> @@ -1128,6 +1128,75 @@ coverage_obj_finish (vec<constructor_elt, va_gc> *ctor)
> varpool_finalize_decl (gcov_info_var);
> }
>
> +/* Check the profile data file.
> + Return -1 if the file is not available or corrupted,
> + 0 if the file is available and all counters are zero,
> + 1 otherwise. */
> +
> +int
> +coverage_check (const char *filename)
> +{
> + int ret = 0;
> + int len = strlen (filename);
> + int prefix_len = 0;
> + gcov_unsigned_t tag;
> + char *data_filename;
> +
> + if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
> + profile_data_prefix = getpwd ();
> +
> + if (profile_data_prefix)
> + prefix_len = strlen (profile_data_prefix);
> +
> + data_filename = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
> + + prefix_len + 2);
> +
> + if (profile_data_prefix)
> + {
> + memcpy (data_filename, profile_data_prefix, prefix_len);
> + data_filename[prefix_len++] = '/';
> + }
> + memcpy (data_filename + prefix_len, filename, len);
> + strcpy (data_filename + prefix_len + len, GCOV_DATA_SUFFIX);
> +
> + if (!gcov_open (data_filename, 1))
> + return -1;
> + if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC)
> + || gcov_read_unsigned () != GCOV_VERSION)
> + {
> + gcov_close ();
> + return -1;
> + }
> + gcov_read_unsigned ();
> +
> + while ((tag = gcov_read_unsigned ()))
> + {
> + gcov_unsigned_t length = gcov_read_unsigned ();
> + gcov_position_t offset = gcov_position ();
> +
> + if (GCOV_TAG_IS_COUNTER (tag))
> + {
> + unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
> + unsigned ix;
> +
> + for (ix = 0; ix != n_counts; ix++)
> + if (gcov_read_counter ())
> + ret = 1;
> + }
> + gcov_sync (offset, length);
> +
> + if (gcov_is_error ())
> + {
> + ret = -1;
> + break;
> + }
> + }
> +
> + gcov_close ();
> +
> + return ret;
> +}
> +
> /* Perform file-level initialization. Read in data file, generate name
> of notes file. */
>
> diff --git a/gcc/coverage.h b/gcc/coverage.h
> index 81f87a6..51d1119 100644
> --- a/gcc/coverage.h
> +++ b/gcc/coverage.h
> @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
>
> #include "gcov-io.h"
>
> +extern int coverage_check (const char *);
> extern void coverage_init (const char *);
> extern void coverage_finish (void);
>
> diff --git a/gcc/toplev.c b/gcc/toplev.c
> index d646faf..b0c3906 100644
> --- a/gcc/toplev.c
> +++ b/gcc/toplev.c
> @@ -1222,6 +1222,77 @@ init_alignments (void)
> align_functions_log = floor_log2 (align_functions * 2 - 1);
> }
>
> +/* Override options based on profile. */
> +
> +static void
> +profile_based_option_override (void)
> +{
> + int status;
> + const char *name = aux_base_name;
> +
> + if (!flag_branch_probabilities)
> + return;
> +
> + if (!name)
> + {
> + char *newname;
> + if (!main_input_filename)
> + return;
> + newname = xstrdup (lbasename (main_input_filename));
> + strip_off_ending (newname, strlen (newname));
> + name = newname;
> + }
> +
> + status = coverage_check (name);
> + if (status > 0)
> + return;
> +
> + /* Profile data file is valid and all profile counters are zero.
> + Prefer optimizing code size. */
> + if (status == 0)
> + {
> + optimize = 2;
> + optimize_size = 1;
> + maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
> + param_values, global_options_set.x_param_values);
> +
> + /* Ignore coverage mismatch since all counters are zero. */
> + diagnostic_classify_diagnostic (global_dc, OPT_Wcoverage_mismatch,
> + DK_IGNORED, UNKNOWN_LOCATION);
> + }
> +
> + if (!flag_profile_use)
> + return;
> +
> + /* Disable optimization options for PGO. */
> + if (!global_options_set.x_flag_profile_values)
> + flag_profile_values = false;
> + if (!global_options_set.x_flag_unroll_loops)
> + flag_unroll_loops = false;
> + if (!global_options_set.x_flag_peel_loops)
> + flag_peel_loops = false;
> + if (!global_options_set.x_flag_tracer)
> + flag_tracer = false;
> + if (!global_options_set.x_flag_value_profile_transformations)
> + flag_value_profile_transformations = false;
> + if (!global_options_set.x_flag_ipa_cp_clone)
> + flag_ipa_cp_clone = false;
> + if (!global_options_set.x_flag_predictive_commoning)
> + flag_predictive_commoning = false;
> + if (!global_options_set.x_flag_unswitch_loops)
> + flag_unswitch_loops = false;
> + if (!global_options_set.x_flag_gcse_after_reload)
> + flag_gcse_after_reload = false;
> + if (!global_options_set.x_flag_tree_loop_vectorize
> + && !global_options_set.x_flag_tree_vectorize)
> + flag_tree_loop_vectorize = false;
> + if (!global_options_set.x_flag_tree_slp_vectorize
> + && !global_options_set.x_flag_tree_vectorize)
> + flag_tree_slp_vectorize = false;
> + if (!global_options_set.x_flag_vect_cost_model)
> + flag_vect_cost_model = VECT_COST_MODEL_CHEAP;
> +}
> +
> /* Process the options that have been parsed. */
> static void
> process_options (void)
> @@ -1245,6 +1316,8 @@ process_options (void)
> so we can correctly initialize debug output. */
> no_backend = lang_hooks.post_options (&main_input_filename);
>
> + profile_based_option_override ();
> +
> /* Some machines may reject certain combinations of options. */
> targetm.target_option.override ();