This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, 4.9/4.10] Profile based option tuning


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 ();


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]