Implement -fprofile-prefix-map.

Message ID 7a7bfa59-8f7c-520b-8061-b6b4f43b84df@suse.cz
State New
Headers
Series Implement -fprofile-prefix-map. |

Commit Message

Martin Liška Nov. 11, 2021, 4:39 p.m. UTC
  It's functionality that is analogous to -ffile-prefix-map, this time
for gcov purpose.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin

	PR gcov-profile/96092

gcc/ChangeLog:

	* common.opt: New option.
	* coverage.c (coverage_begin_function): Emit filename with
	remap_profile_filename.
	* doc/invoke.texi: Document the new option.
	* file-prefix-map.c (add_profile_prefix_map): New.
	(remap_profile_filename): Likewise.
	* file-prefix-map.h (add_profile_prefix_map): Likewise.
	(remap_profile_filename): Likewise.
	* lto-opts.c (lto_write_options): Handle
	OPT_fprofile_prefix_map_.
	* opts-global.c (handle_common_deferred_options): Likewise.
	* opts.c (common_handle_option): Likewise.
	(gen_command_line_string): Likewise.
	* profile.c (output_location): Emit filename with
	remap_profile_filename.
---
  gcc/common.opt        |  4 ++++
  gcc/coverage.c        |  3 ++-
  gcc/doc/invoke.texi   | 14 ++++++++++++--
  gcc/file-prefix-map.c | 17 +++++++++++++++++
  gcc/file-prefix-map.h |  2 ++
  gcc/lto-opts.c        |  1 +
  gcc/opts-global.c     |  4 ++++
  gcc/opts.c            |  2 ++
  gcc/profile.c         |  4 ++++
  9 files changed, 48 insertions(+), 3 deletions(-)
  

Comments

Martin Liška Dec. 2, 2021, 11:40 a.m. UTC | #1
PING^1

On 11/11/21 17:39, Martin Liška wrote:
> It's functionality that is analogous to -ffile-prefix-map, this time
> for gcov purpose.
> 
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> Ready to be installed?
> Thanks,
> Martin
> 
>      PR gcov-profile/96092
> 
> gcc/ChangeLog:
> 
>      * common.opt: New option.
>      * coverage.c (coverage_begin_function): Emit filename with
>      remap_profile_filename.
>      * doc/invoke.texi: Document the new option.
>      * file-prefix-map.c (add_profile_prefix_map): New.
>      (remap_profile_filename): Likewise.
>      * file-prefix-map.h (add_profile_prefix_map): Likewise.
>      (remap_profile_filename): Likewise.
>      * lto-opts.c (lto_write_options): Handle
>      OPT_fprofile_prefix_map_.
>      * opts-global.c (handle_common_deferred_options): Likewise.
>      * opts.c (common_handle_option): Likewise.
>      (gen_command_line_string): Likewise.
>      * profile.c (output_location): Emit filename with
>      remap_profile_filename.
> ---
>   gcc/common.opt        |  4 ++++
>   gcc/coverage.c        |  3 ++-
>   gcc/doc/invoke.texi   | 14 ++++++++++++--
>   gcc/file-prefix-map.c | 17 +++++++++++++++++
>   gcc/file-prefix-map.h |  2 ++
>   gcc/lto-opts.c        |  1 +
>   gcc/opts-global.c     |  4 ++++
>   gcc/opts.c            |  2 ++
>   gcc/profile.c         |  4 ++++
>   9 files changed, 48 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/common.opt b/gcc/common.opt
> index de9b848eda5..0b59b46b875 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -2323,6 +2323,10 @@ fprofile-prefix-path=
>   Common Joined RejectNegative Var(profile_prefix_path)
>   Remove prefix from absolute path before mangling name for -fprofile-generate= and -fprofile-use=.
> 
> +fprofile-prefix-map=
> +Common Joined RejectNegative Var(common_deferred_options) Defer
> +-fprofile-prefix-map=<old>=<new>    Map one directory name to another in GCOV coverage result.
> +
>   fprofile-generate
>   Common
>   Enable common options for generating profile info for profile feedback directed optimizations.
> diff --git a/gcc/coverage.c b/gcc/coverage.c
> index 4daa3f9fc30..7f8b532cb52 100644
> --- a/gcc/coverage.c
> +++ b/gcc/coverage.c
> @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "profile.h"
>   #include "diagnostic.h"
>   #include "varasm.h"
> +#include "file-prefix-map.h"
> 
>   #include "gcov-io.c"
> 
> @@ -646,7 +647,7 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
>     gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl)
>                  && !DECL_FUNCTION_VERSIONED (current_function_decl)
>                  && !DECL_LAMBDA_FUNCTION_P (current_function_decl));
> -  gcov_write_filename (startloc.file);
> +  gcov_write_filename (remap_profile_filename (startloc.file));
>     gcov_write_unsigned (startloc.line);
>     gcov_write_unsigned (startloc.column);
> 
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 2aba4c70b44..5fb6a8bfffe 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -606,7 +606,8 @@ Objective-C and Objective-C++ Dialects}.
>   -fvtv-counts  -fvtv-debug @gol
>   -finstrument-functions @gol
>   -finstrument-functions-exclude-function-list=@var{sym},@var{sym},@dots{} @gol
> --finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{}}
> +-finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{}} @gol
> +-fprofile-prefix-map=@var{old}=@var{new}
> 
>   @item Preprocessor Options
>   @xref{Preprocessor Options,,Options Controlling the Preprocessor}.
> @@ -2173,7 +2174,8 @@ files resided in directory @file{@var{new}} instead.  Specifying this
>   option is equivalent to specifying all the individual
>   @option{-f*-prefix-map} options.  This can be used to make reproducible
>   builds that are location independent.  See also
> -@option{-fmacro-prefix-map} and @option{-fdebug-prefix-map}.
> +@option{-fmacro-prefix-map}, @option{-fdebug-prefix-map} and
> +@option{-fprofile-prefix-map}.
> 
>   @item -fplugin=@var{name}.so
>   @opindex fplugin
> @@ -15155,6 +15157,14 @@ In such setups @option{-fprofile-prefix-path=}@var{path} with @var{path}
>   pointing to the base directory of the build can be used to strip the irrelevant
>   part of the path and keep all file names relative to the main build directory.
> 
> +@item -fprofile-prefix-map=@var{old}=@var{new}
> +@opindex fprofile-prefix-map
> +When compiling files residing in directory @file{@var{old}}, record
> +profiling information (with @option{--coverage})
> +describing them as if the files resided in
> +directory @file{@var{new}} instead.
> +See also @option{-ffile-prefix-map}.
> +
>   @item -fprofile-update=@var{method}
>   @opindex fprofile-update
> 
> diff --git a/gcc/file-prefix-map.c b/gcc/file-prefix-map.c
> index ad242e5b9c5..290b4b2da33 100644
> --- a/gcc/file-prefix-map.c
> +++ b/gcc/file-prefix-map.c
> @@ -92,6 +92,7 @@ remap_filename (file_prefix_map *maps, const char *filename)
>   /* Linked lists of file_prefix_map structures.  */
>   static file_prefix_map *macro_prefix_maps; /* -fmacro-prefix-map  */
>   static file_prefix_map *debug_prefix_maps; /* -fdebug-prefix-map  */
> +static file_prefix_map *profile_prefix_maps; /* -fprofile-prefix-map  */
> 
>   /* Record a file prefix mapping for -fmacro-prefix-map.  */
>   void
> @@ -113,6 +114,14 @@ add_file_prefix_map (const char *arg)
>   {
>     add_prefix_map (macro_prefix_maps, arg, "-ffile-prefix-map");
>     add_prefix_map (debug_prefix_maps, arg, "-ffile-prefix-map");
> +  add_prefix_map (profile_prefix_maps, arg, "-ffile-prefix-map");
> +}
> +
> +/* Record a file prefix mapping for -fprofile-prefix-map.  */
> +void
> +add_profile_prefix_map (const char *arg)
> +{
> +  add_prefix_map (profile_prefix_maps, arg, "-fprofile-prefix-map");
>   }
> 
>   /* Remap using -fmacro-prefix-map.  Return the GC-allocated new name
> @@ -130,3 +139,11 @@ remap_debug_filename (const char *filename)
>   {
>     return remap_filename (debug_prefix_maps, filename);
>   }
> +
> +/* Remap using -fprofile-prefix-map.  Return the GC-allocated new name
> +   corresponding to FILENAME or FILENAME if no remapping was performed.  */
> +const char *
> +remap_profile_filename (const char *filename)
> +{
> +  return remap_filename (profile_prefix_maps, filename);
> +}
> diff --git a/gcc/file-prefix-map.h b/gcc/file-prefix-map.h
> index 5aecd5f7e19..3a2b0605ae0 100644
> --- a/gcc/file-prefix-map.h
> +++ b/gcc/file-prefix-map.h
> @@ -21,8 +21,10 @@
>   void add_macro_prefix_map (const char *);
>   void add_debug_prefix_map (const char *);
>   void add_file_prefix_map (const char *);
> +void add_profile_prefix_map (const char *);
> 
>   const char *remap_macro_filename (const char *);
>   const char *remap_debug_filename (const char *);
> +const char *remap_profile_filename (const char *);
> 
>   #endif /* !GCC_FILE_PREFIX_MAP_H  */
> diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c
> index 7b2ad74e69a..30c10136f31 100644
> --- a/gcc/lto-opts.c
> +++ b/gcc/lto-opts.c
> @@ -149,6 +149,7 @@ lto_write_options (void)
>       case OPT_fdebug_prefix_map_:
>       case OPT_ffile_prefix_map_:
>       case OPT_fmacro_prefix_map_:
> +    case OPT_fprofile_prefix_map_:
>         continue;
> 
>       default:
> diff --git a/gcc/opts-global.c b/gcc/opts-global.c
> index 55273822ec5..d4fde39b9bd 100644
> --- a/gcc/opts-global.c
> +++ b/gcc/opts-global.c
> @@ -386,6 +386,10 @@ handle_common_deferred_options (void)
>         add_file_prefix_map (opt->arg);
>         break;
> 
> +    case OPT_fprofile_prefix_map_:
> +      add_profile_prefix_map (opt->arg);
> +      break;
> +
>       case OPT_fdump_:
>         g->get_dumps ()->dump_switch_p (opt->arg);
>         break;
> diff --git a/gcc/opts.c b/gcc/opts.c
> index 175b4635bb4..255f4ac0def 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -2684,6 +2684,7 @@ common_handle_option (struct gcc_options *opts,
> 
>       case OPT_fdebug_prefix_map_:
>       case OPT_ffile_prefix_map_:
> +    case OPT_fprofile_prefix_map_:
>         /* Deferred.  */
>         break;
> 
> @@ -3597,6 +3598,7 @@ gen_command_line_string (cl_decoded_option *options,
>         case OPT_fdebug_prefix_map_:
>         case OPT_fmacro_prefix_map_:
>         case OPT_ffile_prefix_map_:
> +      case OPT_fprofile_prefix_map_:
>         case OPT_fcompare_debug:
>         case OPT_fchecking:
>         case OPT_fchecking_:
> diff --git a/gcc/profile.c b/gcc/profile.c
> index c33c833167f..ed7398fe7df 100644
> --- a/gcc/profile.c
> +++ b/gcc/profile.c
> @@ -64,6 +64,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "tree-cfg.h"
>   #include "dumpfile.h"
>   #include "cfgloop.h"
> +#include "file-prefix-map.h"
> 
>   #include "profile.h"
> 
> @@ -992,6 +993,9 @@ output_location (hash_set<location_triplet_hash> *streamed_locations,
>     static int prev_line;
>     bool name_differs, line_differs;
> 
> +  if (file_name != NULL)
> +    file_name = remap_profile_filename (file_name);
> +
>     location_triplet triplet;
>     triplet.filename = file_name;
>     triplet.lineno = line;
  
Richard Biener Dec. 2, 2021, 11:57 a.m. UTC | #2
On Thu, Dec 2, 2021 at 12:43 PM Martin Liška <mliska@suse.cz> wrote:
>
> PING^1

OK.

> On 11/11/21 17:39, Martin Liška wrote:
> > It's functionality that is analogous to -ffile-prefix-map, this time
> > for gcov purpose.
> >
> > Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >
> > Ready to be installed?
> > Thanks,
> > Martin
> >
> >      PR gcov-profile/96092
> >
> > gcc/ChangeLog:
> >
> >      * common.opt: New option.
> >      * coverage.c (coverage_begin_function): Emit filename with
> >      remap_profile_filename.
> >      * doc/invoke.texi: Document the new option.
> >      * file-prefix-map.c (add_profile_prefix_map): New.
> >      (remap_profile_filename): Likewise.
> >      * file-prefix-map.h (add_profile_prefix_map): Likewise.
> >      (remap_profile_filename): Likewise.
> >      * lto-opts.c (lto_write_options): Handle
> >      OPT_fprofile_prefix_map_.
> >      * opts-global.c (handle_common_deferred_options): Likewise.
> >      * opts.c (common_handle_option): Likewise.
> >      (gen_command_line_string): Likewise.
> >      * profile.c (output_location): Emit filename with
> >      remap_profile_filename.
> > ---
> >   gcc/common.opt        |  4 ++++
> >   gcc/coverage.c        |  3 ++-
> >   gcc/doc/invoke.texi   | 14 ++++++++++++--
> >   gcc/file-prefix-map.c | 17 +++++++++++++++++
> >   gcc/file-prefix-map.h |  2 ++
> >   gcc/lto-opts.c        |  1 +
> >   gcc/opts-global.c     |  4 ++++
> >   gcc/opts.c            |  2 ++
> >   gcc/profile.c         |  4 ++++
> >   9 files changed, 48 insertions(+), 3 deletions(-)
> >
> > diff --git a/gcc/common.opt b/gcc/common.opt
> > index de9b848eda5..0b59b46b875 100644
> > --- a/gcc/common.opt
> > +++ b/gcc/common.opt
> > @@ -2323,6 +2323,10 @@ fprofile-prefix-path=
> >   Common Joined RejectNegative Var(profile_prefix_path)
> >   Remove prefix from absolute path before mangling name for -fprofile-generate= and -fprofile-use=.
> >
> > +fprofile-prefix-map=
> > +Common Joined RejectNegative Var(common_deferred_options) Defer
> > +-fprofile-prefix-map=<old>=<new>    Map one directory name to another in GCOV coverage result.
> > +
> >   fprofile-generate
> >   Common
> >   Enable common options for generating profile info for profile feedback directed optimizations.
> > diff --git a/gcc/coverage.c b/gcc/coverage.c
> > index 4daa3f9fc30..7f8b532cb52 100644
> > --- a/gcc/coverage.c
> > +++ b/gcc/coverage.c
> > @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
> >   #include "profile.h"
> >   #include "diagnostic.h"
> >   #include "varasm.h"
> > +#include "file-prefix-map.h"
> >
> >   #include "gcov-io.c"
> >
> > @@ -646,7 +647,7 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
> >     gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl)
> >                  && !DECL_FUNCTION_VERSIONED (current_function_decl)
> >                  && !DECL_LAMBDA_FUNCTION_P (current_function_decl));
> > -  gcov_write_filename (startloc.file);
> > +  gcov_write_filename (remap_profile_filename (startloc.file));
> >     gcov_write_unsigned (startloc.line);
> >     gcov_write_unsigned (startloc.column);
> >
> > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> > index 2aba4c70b44..5fb6a8bfffe 100644
> > --- a/gcc/doc/invoke.texi
> > +++ b/gcc/doc/invoke.texi
> > @@ -606,7 +606,8 @@ Objective-C and Objective-C++ Dialects}.
> >   -fvtv-counts  -fvtv-debug @gol
> >   -finstrument-functions @gol
> >   -finstrument-functions-exclude-function-list=@var{sym},@var{sym},@dots{} @gol
> > --finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{}}
> > +-finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{}} @gol
> > +-fprofile-prefix-map=@var{old}=@var{new}
> >
> >   @item Preprocessor Options
> >   @xref{Preprocessor Options,,Options Controlling the Preprocessor}.
> > @@ -2173,7 +2174,8 @@ files resided in directory @file{@var{new}} instead.  Specifying this
> >   option is equivalent to specifying all the individual
> >   @option{-f*-prefix-map} options.  This can be used to make reproducible
> >   builds that are location independent.  See also
> > -@option{-fmacro-prefix-map} and @option{-fdebug-prefix-map}.
> > +@option{-fmacro-prefix-map}, @option{-fdebug-prefix-map} and
> > +@option{-fprofile-prefix-map}.
> >
> >   @item -fplugin=@var{name}.so
> >   @opindex fplugin
> > @@ -15155,6 +15157,14 @@ In such setups @option{-fprofile-prefix-path=}@var{path} with @var{path}
> >   pointing to the base directory of the build can be used to strip the irrelevant
> >   part of the path and keep all file names relative to the main build directory.
> >
> > +@item -fprofile-prefix-map=@var{old}=@var{new}
> > +@opindex fprofile-prefix-map
> > +When compiling files residing in directory @file{@var{old}}, record
> > +profiling information (with @option{--coverage})
> > +describing them as if the files resided in
> > +directory @file{@var{new}} instead.
> > +See also @option{-ffile-prefix-map}.
> > +
> >   @item -fprofile-update=@var{method}
> >   @opindex fprofile-update
> >
> > diff --git a/gcc/file-prefix-map.c b/gcc/file-prefix-map.c
> > index ad242e5b9c5..290b4b2da33 100644
> > --- a/gcc/file-prefix-map.c
> > +++ b/gcc/file-prefix-map.c
> > @@ -92,6 +92,7 @@ remap_filename (file_prefix_map *maps, const char *filename)
> >   /* Linked lists of file_prefix_map structures.  */
> >   static file_prefix_map *macro_prefix_maps; /* -fmacro-prefix-map  */
> >   static file_prefix_map *debug_prefix_maps; /* -fdebug-prefix-map  */
> > +static file_prefix_map *profile_prefix_maps; /* -fprofile-prefix-map  */
> >
> >   /* Record a file prefix mapping for -fmacro-prefix-map.  */
> >   void
> > @@ -113,6 +114,14 @@ add_file_prefix_map (const char *arg)
> >   {
> >     add_prefix_map (macro_prefix_maps, arg, "-ffile-prefix-map");
> >     add_prefix_map (debug_prefix_maps, arg, "-ffile-prefix-map");
> > +  add_prefix_map (profile_prefix_maps, arg, "-ffile-prefix-map");
> > +}
> > +
> > +/* Record a file prefix mapping for -fprofile-prefix-map.  */
> > +void
> > +add_profile_prefix_map (const char *arg)
> > +{
> > +  add_prefix_map (profile_prefix_maps, arg, "-fprofile-prefix-map");
> >   }
> >
> >   /* Remap using -fmacro-prefix-map.  Return the GC-allocated new name
> > @@ -130,3 +139,11 @@ remap_debug_filename (const char *filename)
> >   {
> >     return remap_filename (debug_prefix_maps, filename);
> >   }
> > +
> > +/* Remap using -fprofile-prefix-map.  Return the GC-allocated new name
> > +   corresponding to FILENAME or FILENAME if no remapping was performed.  */
> > +const char *
> > +remap_profile_filename (const char *filename)
> > +{
> > +  return remap_filename (profile_prefix_maps, filename);
> > +}
> > diff --git a/gcc/file-prefix-map.h b/gcc/file-prefix-map.h
> > index 5aecd5f7e19..3a2b0605ae0 100644
> > --- a/gcc/file-prefix-map.h
> > +++ b/gcc/file-prefix-map.h
> > @@ -21,8 +21,10 @@
> >   void add_macro_prefix_map (const char *);
> >   void add_debug_prefix_map (const char *);
> >   void add_file_prefix_map (const char *);
> > +void add_profile_prefix_map (const char *);
> >
> >   const char *remap_macro_filename (const char *);
> >   const char *remap_debug_filename (const char *);
> > +const char *remap_profile_filename (const char *);
> >
> >   #endif /* !GCC_FILE_PREFIX_MAP_H  */
> > diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c
> > index 7b2ad74e69a..30c10136f31 100644
> > --- a/gcc/lto-opts.c
> > +++ b/gcc/lto-opts.c
> > @@ -149,6 +149,7 @@ lto_write_options (void)
> >       case OPT_fdebug_prefix_map_:
> >       case OPT_ffile_prefix_map_:
> >       case OPT_fmacro_prefix_map_:
> > +    case OPT_fprofile_prefix_map_:
> >         continue;
> >
> >       default:
> > diff --git a/gcc/opts-global.c b/gcc/opts-global.c
> > index 55273822ec5..d4fde39b9bd 100644
> > --- a/gcc/opts-global.c
> > +++ b/gcc/opts-global.c
> > @@ -386,6 +386,10 @@ handle_common_deferred_options (void)
> >         add_file_prefix_map (opt->arg);
> >         break;
> >
> > +    case OPT_fprofile_prefix_map_:
> > +      add_profile_prefix_map (opt->arg);
> > +      break;
> > +
> >       case OPT_fdump_:
> >         g->get_dumps ()->dump_switch_p (opt->arg);
> >         break;
> > diff --git a/gcc/opts.c b/gcc/opts.c
> > index 175b4635bb4..255f4ac0def 100644
> > --- a/gcc/opts.c
> > +++ b/gcc/opts.c
> > @@ -2684,6 +2684,7 @@ common_handle_option (struct gcc_options *opts,
> >
> >       case OPT_fdebug_prefix_map_:
> >       case OPT_ffile_prefix_map_:
> > +    case OPT_fprofile_prefix_map_:
> >         /* Deferred.  */
> >         break;
> >
> > @@ -3597,6 +3598,7 @@ gen_command_line_string (cl_decoded_option *options,
> >         case OPT_fdebug_prefix_map_:
> >         case OPT_fmacro_prefix_map_:
> >         case OPT_ffile_prefix_map_:
> > +      case OPT_fprofile_prefix_map_:
> >         case OPT_fcompare_debug:
> >         case OPT_fchecking:
> >         case OPT_fchecking_:
> > diff --git a/gcc/profile.c b/gcc/profile.c
> > index c33c833167f..ed7398fe7df 100644
> > --- a/gcc/profile.c
> > +++ b/gcc/profile.c
> > @@ -64,6 +64,7 @@ along with GCC; see the file COPYING3.  If not see
> >   #include "tree-cfg.h"
> >   #include "dumpfile.h"
> >   #include "cfgloop.h"
> > +#include "file-prefix-map.h"
> >
> >   #include "profile.h"
> >
> > @@ -992,6 +993,9 @@ output_location (hash_set<location_triplet_hash> *streamed_locations,
> >     static int prev_line;
> >     bool name_differs, line_differs;
> >
> > +  if (file_name != NULL)
> > +    file_name = remap_profile_filename (file_name);
> > +
> >     location_triplet triplet;
> >     triplet.filename = file_name;
> >     triplet.lineno = line;
>
  

Patch

diff --git a/gcc/common.opt b/gcc/common.opt
index de9b848eda5..0b59b46b875 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2323,6 +2323,10 @@  fprofile-prefix-path=
  Common Joined RejectNegative Var(profile_prefix_path)
  Remove prefix from absolute path before mangling name for -fprofile-generate= and -fprofile-use=.
  
+fprofile-prefix-map=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fprofile-prefix-map=<old>=<new>	Map one directory name to another in GCOV coverage result.
+
  fprofile-generate
  Common
  Enable common options for generating profile info for profile feedback directed optimizations.
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 4daa3f9fc30..7f8b532cb52 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -51,6 +51,7 @@  along with GCC; see the file COPYING3.  If not see
  #include "profile.h"
  #include "diagnostic.h"
  #include "varasm.h"
+#include "file-prefix-map.h"
  
  #include "gcov-io.c"
  
@@ -646,7 +647,7 @@  coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
    gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl)
  		       && !DECL_FUNCTION_VERSIONED (current_function_decl)
  		       && !DECL_LAMBDA_FUNCTION_P (current_function_decl));
-  gcov_write_filename (startloc.file);
+  gcov_write_filename (remap_profile_filename (startloc.file));
    gcov_write_unsigned (startloc.line);
    gcov_write_unsigned (startloc.column);
  
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 2aba4c70b44..5fb6a8bfffe 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -606,7 +606,8 @@  Objective-C and Objective-C++ Dialects}.
  -fvtv-counts  -fvtv-debug @gol
  -finstrument-functions @gol
  -finstrument-functions-exclude-function-list=@var{sym},@var{sym},@dots{} @gol
--finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{}}
+-finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{}} @gol
+-fprofile-prefix-map=@var{old}=@var{new}
  
  @item Preprocessor Options
  @xref{Preprocessor Options,,Options Controlling the Preprocessor}.
@@ -2173,7 +2174,8 @@  files resided in directory @file{@var{new}} instead.  Specifying this
  option is equivalent to specifying all the individual
  @option{-f*-prefix-map} options.  This can be used to make reproducible
  builds that are location independent.  See also
-@option{-fmacro-prefix-map} and @option{-fdebug-prefix-map}.
+@option{-fmacro-prefix-map}, @option{-fdebug-prefix-map} and
+@option{-fprofile-prefix-map}.
  
  @item -fplugin=@var{name}.so
  @opindex fplugin
@@ -15155,6 +15157,14 @@  In such setups @option{-fprofile-prefix-path=}@var{path} with @var{path}
  pointing to the base directory of the build can be used to strip the irrelevant
  part of the path and keep all file names relative to the main build directory.
  
+@item -fprofile-prefix-map=@var{old}=@var{new}
+@opindex fprofile-prefix-map
+When compiling files residing in directory @file{@var{old}}, record
+profiling information (with @option{--coverage})
+describing them as if the files resided in
+directory @file{@var{new}} instead.
+See also @option{-ffile-prefix-map}.
+
  @item -fprofile-update=@var{method}
  @opindex fprofile-update
  
diff --git a/gcc/file-prefix-map.c b/gcc/file-prefix-map.c
index ad242e5b9c5..290b4b2da33 100644
--- a/gcc/file-prefix-map.c
+++ b/gcc/file-prefix-map.c
@@ -92,6 +92,7 @@  remap_filename (file_prefix_map *maps, const char *filename)
  /* Linked lists of file_prefix_map structures.  */
  static file_prefix_map *macro_prefix_maps; /* -fmacro-prefix-map  */
  static file_prefix_map *debug_prefix_maps; /* -fdebug-prefix-map  */
+static file_prefix_map *profile_prefix_maps; /* -fprofile-prefix-map  */
  
  /* Record a file prefix mapping for -fmacro-prefix-map.  */
  void
@@ -113,6 +114,14 @@  add_file_prefix_map (const char *arg)
  {
    add_prefix_map (macro_prefix_maps, arg, "-ffile-prefix-map");
    add_prefix_map (debug_prefix_maps, arg, "-ffile-prefix-map");
+  add_prefix_map (profile_prefix_maps, arg, "-ffile-prefix-map");
+}
+
+/* Record a file prefix mapping for -fprofile-prefix-map.  */
+void
+add_profile_prefix_map (const char *arg)
+{
+  add_prefix_map (profile_prefix_maps, arg, "-fprofile-prefix-map");
  }
  
  /* Remap using -fmacro-prefix-map.  Return the GC-allocated new name
@@ -130,3 +139,11 @@  remap_debug_filename (const char *filename)
  {
    return remap_filename (debug_prefix_maps, filename);
  }
+
+/* Remap using -fprofile-prefix-map.  Return the GC-allocated new name
+   corresponding to FILENAME or FILENAME if no remapping was performed.  */
+const char *
+remap_profile_filename (const char *filename)
+{
+  return remap_filename (profile_prefix_maps, filename);
+}
diff --git a/gcc/file-prefix-map.h b/gcc/file-prefix-map.h
index 5aecd5f7e19..3a2b0605ae0 100644
--- a/gcc/file-prefix-map.h
+++ b/gcc/file-prefix-map.h
@@ -21,8 +21,10 @@ 
  void add_macro_prefix_map (const char *);
  void add_debug_prefix_map (const char *);
  void add_file_prefix_map (const char *);
+void add_profile_prefix_map (const char *);
  
  const char *remap_macro_filename (const char *);
  const char *remap_debug_filename (const char *);
+const char *remap_profile_filename (const char *);
  
  #endif /* !GCC_FILE_PREFIX_MAP_H  */
diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c
index 7b2ad74e69a..30c10136f31 100644
--- a/gcc/lto-opts.c
+++ b/gcc/lto-opts.c
@@ -149,6 +149,7 @@  lto_write_options (void)
  	case OPT_fdebug_prefix_map_:
  	case OPT_ffile_prefix_map_:
  	case OPT_fmacro_prefix_map_:
+	case OPT_fprofile_prefix_map_:
  	  continue;
  
  	default:
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 55273822ec5..d4fde39b9bd 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -386,6 +386,10 @@  handle_common_deferred_options (void)
  	  add_file_prefix_map (opt->arg);
  	  break;
  
+	case OPT_fprofile_prefix_map_:
+	  add_profile_prefix_map (opt->arg);
+	  break;
+
  	case OPT_fdump_:
  	  g->get_dumps ()->dump_switch_p (opt->arg);
  	  break;
diff --git a/gcc/opts.c b/gcc/opts.c
index 175b4635bb4..255f4ac0def 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2684,6 +2684,7 @@  common_handle_option (struct gcc_options *opts,
  
      case OPT_fdebug_prefix_map_:
      case OPT_ffile_prefix_map_:
+    case OPT_fprofile_prefix_map_:
        /* Deferred.  */
        break;
  
@@ -3597,6 +3598,7 @@  gen_command_line_string (cl_decoded_option *options,
        case OPT_fdebug_prefix_map_:
        case OPT_fmacro_prefix_map_:
        case OPT_ffile_prefix_map_:
+      case OPT_fprofile_prefix_map_:
        case OPT_fcompare_debug:
        case OPT_fchecking:
        case OPT_fchecking_:
diff --git a/gcc/profile.c b/gcc/profile.c
index c33c833167f..ed7398fe7df 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -64,6 +64,7 @@  along with GCC; see the file COPYING3.  If not see
  #include "tree-cfg.h"
  #include "dumpfile.h"
  #include "cfgloop.h"
+#include "file-prefix-map.h"
  
  #include "profile.h"
  
@@ -992,6 +993,9 @@  output_location (hash_set<location_triplet_hash> *streamed_locations,
    static int prev_line;
    bool name_differs, line_differs;
  
+  if (file_name != NULL)
+    file_name = remap_profile_filename (file_name);
+
    location_triplet triplet;
    triplet.filename = file_name;
    triplet.lineno = line;