diff mbox

[google] Remove deprecated pfmon-specific functions/structs from pmu-profile.c (issue6442086)

Message ID 20120807225534.AA4DF140ADD@rainbowponydeluxe.mtv.corp.google.com
State New
Headers show

Commit Message

Chris Manghane Aug. 7, 2012, 10:55 p.m. UTC
Removes references in libgcov.c to functions and structs removed from
pmu-profile.c

For google/main. Tested with crosstools and bootstrap.

2012-08-07  Chris Manghane  <cmang@google.com>

	* libgcc/pmu-profile.c
	(enum pmu_tool_type): Remove pfmon-specific functions/structs.
	(enum pmu_event_type): Ditto.
	(enum pmu_state): Ditto.
	(enum cpu_vendor_signature): Ditto.
	(struct pmu_tool_info): Ditto.
	(void gcov_write_branch_mispredict_infos): Ditto.
	(get_x86cpu_vendor): Ditto.
	(parse_pmu_profile_options): Ditto.
	(start_addr2line_symbolizer): Ditto.
	(reset_symbolizer_parent_pipes): Ditto.
	(reset_symbolizer_child_pipes): Ditto.
	(end_addr2line_symbolizer): Ditto.
	(symbolize_addr2line): Ditto.
	(start_pfmon_module): Ditto.
	(convert_pct_to_unsigned): Ditto.
	(parse_load_latency_line): Ditto.
	(parse_branch_mispredict_line): Ditto.
	(parse_pfmon_load_latency): Ditto.
	(parse_pfmon_tool_header): Ditto.
	(parse_pfmon_branch_mispredicts): Ditto.
	(pmu_start): Ditto.
	(init_pmu_branch_mispredict): Ditto.
	(init_pmu_tool): Ditto.
	(__gcov_init_pmu_profiler): Ditto.
	(__gcov_start_pmu_profiler): Ditto.
	(__gcov_stop_pmu_profiler): Ditto.
	(gcov_write_branch_mispredict_line): Ditto.
	(gcov_write_load_latency_infos): Ditto.
	(gcov_write_branch_mispredict_infos): Ditto.
	(gcov_write_tool_header): Ditto.
	(__gcov_end_pmu_profiler): Ditto.
	* libgcc/libgcov.c
	(gcov_alloc_filename): Remove references to pfmon specific 
	functions/structs.
	(pmu_profile_stop): Ditto.
	(gcov_exit): Ditto.
	(__gcov_init): Ditto.
	(__gcov_flush): Ditto.


--
This patch is available for review at http://codereview.appspot.com/6442086

Comments

Teresa Johnson Aug. 9, 2012, 2:47 a.m. UTC | #1
I have committed this to google/main for Chris (approved by Rong).
Chris, please prepare a patch to backport this to google/4_7.

Teresa

On Tue, Aug 7, 2012 at 3:55 PM, Chris Manghane <cmang@google.com> wrote:
> Removes references in libgcov.c to functions and structs removed from
> pmu-profile.c
>
> For google/main. Tested with crosstools and bootstrap.
>
> 2012-08-07  Chris Manghane  <cmang@google.com>
>
>         * libgcc/pmu-profile.c
>         (enum pmu_tool_type): Remove pfmon-specific functions/structs.
>         (enum pmu_event_type): Ditto.
>         (enum pmu_state): Ditto.
>         (enum cpu_vendor_signature): Ditto.
>         (struct pmu_tool_info): Ditto.
>         (void gcov_write_branch_mispredict_infos): Ditto.
>         (get_x86cpu_vendor): Ditto.
>         (parse_pmu_profile_options): Ditto.
>         (start_addr2line_symbolizer): Ditto.
>         (reset_symbolizer_parent_pipes): Ditto.
>         (reset_symbolizer_child_pipes): Ditto.
>         (end_addr2line_symbolizer): Ditto.
>         (symbolize_addr2line): Ditto.
>         (start_pfmon_module): Ditto.
>         (convert_pct_to_unsigned): Ditto.
>         (parse_load_latency_line): Ditto.
>         (parse_branch_mispredict_line): Ditto.
>         (parse_pfmon_load_latency): Ditto.
>         (parse_pfmon_tool_header): Ditto.
>         (parse_pfmon_branch_mispredicts): Ditto.
>         (pmu_start): Ditto.
>         (init_pmu_branch_mispredict): Ditto.
>         (init_pmu_tool): Ditto.
>         (__gcov_init_pmu_profiler): Ditto.
>         (__gcov_start_pmu_profiler): Ditto.
>         (__gcov_stop_pmu_profiler): Ditto.
>         (gcov_write_branch_mispredict_line): Ditto.
>         (gcov_write_load_latency_infos): Ditto.
>         (gcov_write_branch_mispredict_infos): Ditto.
>         (gcov_write_tool_header): Ditto.
>         (__gcov_end_pmu_profiler): Ditto.
>         * libgcc/libgcov.c
>         (gcov_alloc_filename): Remove references to pfmon specific
>         functions/structs.
>         (pmu_profile_stop): Ditto.
>         (gcov_exit): Ditto.
>         (__gcov_init): Ditto.
>         (__gcov_flush): Ditto.
>
> Index: libgcc/pmu-profile.c
> ===================================================================
> --- libgcc/pmu-profile.c        (revision 190135)
> +++ libgcc/pmu-profile.c        (working copy)
> @@ -67,169 +67,11 @@ see the files COPYING3 and COPYING.RUNTIME respect
>  #define XDELETEVEC(p) free(p)
>  #define XDELETE(p) free(p)
>
> -#define PFMON_CMD "/usr/bin/pfmon"
> -#define ADDR2LINE_CMD "/usr/bin/addr2line"
> -#define PMU_TOOL_MAX_ARGS (20)
> -static char default_addr2line[] = "??:0";
> -static const char pfmon_ll_header[] = "#     counts   %self    %cum     "
> -    "<10     <32     <64    <256   <1024  >=1024  %wself          "
> -    "code addr symbol\n";
> -static const char pfmon_bm_header[] =
> -    "#     counts   %self    %cum          code addr symbol\n";
> -
> -const char *pfmon_intel_ll_args[PMU_TOOL_MAX_ARGS] = {
> -  PFMON_CMD,
> -  "--aggregate-results",
> -  "--follow-all",
> -  "--with-header",
> -  "--smpl-module=pebs-ll",
> -  "--ld-lat-threshold=4",
> -  "--pebs-ll-dcmiss-code",
> -  "--resolve-addresses",
> -  "-emem_inst_retired:LATENCY_ABOVE_THRESHOLD",
> -  "--long-smpl-periods=10000",
> -  0  /* terminating NULL must be present */
> -};
> -
> -const char *pfmon_amd_ll_args[PMU_TOOL_MAX_ARGS] = {
> -  PFMON_CMD,
> -  "--aggregate-results",
> -  "--follow-all",
> -  "-uk",
> -  "--with-header",
> -  "--smpl-module=ibs",
> -  "--resolve-addresses",
> -  "-eibsop_event:uops",
> -  "--ibs-dcmiss-code",
> -  "--long-smpl-periods=0xffff0",
> -  0  /* terminating NULL must be present */
> -};
> -
> -const char *pfmon_intel_brm_args[PMU_TOOL_MAX_ARGS] = {
> -  PFMON_CMD,
> -  "--aggregate-results",
> -  "--follow-all",
> -  "--with-header",
> -  "--resolve-addresses",
> -  "-eMISPREDICTED_BRANCH_RETIRED",
> -  "--long-smpl-periods=10000",
> -  0  /* terminating NULL must be present */
> -};
> -
> -const char *pfmon_amd_brm_args[PMU_TOOL_MAX_ARGS] = {
> -  PFMON_CMD,
> -  "--aggregate-results",
> -  "--follow-all",
> -  "--with-header",
> -  "--resolve-addresses",
> -  "-eRETIRED_MISPREDICTED_BRANCH_INSTRUCTIONS",
> -  "--long-smpl-periods=10000",
> -  0  /* terminating NULL must be present */
> -};
> -
> -const char *addr2line_args[PMU_TOOL_MAX_ARGS] = {
> -  ADDR2LINE_CMD,
> -  "-e",
> -  0  /* terminating NULL must be present */
> -};
> -
> -
> -enum pmu_tool_type
> -{
> -  PTT_PFMON,
> -  PTT_LAST
> -};
> -
> -enum pmu_event_type
> -{
> -  PET_INTEL_LOAD_LATENCY,
> -  PET_AMD_LOAD_LATENCY,
> -  PET_INTEL_BRANCH_MISPREDICT,
> -  PET_AMD_BRANCH_MISPREDICT,
> -  PET_LAST
> -};
> -
> -typedef struct pmu_tool_fns {
> -  const char *name;     /* name of the pmu tool */
> -  /* pmu tool commandline argument.  */
> -  const char **arg_array;
> -  /* Initialize pmu module.  */
> -  void *(*init_pmu_module) (void);
> -  /* Start profililing.  */
> -  void (*start_pmu_module) (pid_t ppid, char *tmpfile, const char **args);
> -  /* Stop profililing.  */
> -  void (*stop_pmu_module) (void);
> -  /* How to parse the output generated by the PMU tool.  */
> -  int (*parse_pmu_output) (char *filename, void *pmu_data);
> -  /* How to write parsed pmu data into gcda file.  */
> -  void (*gcov_write_pmu_data) (void *data);
> -  /* How to cleanup any data structure created during parsing.  */
> -  void (*cleanup_pmu_data) (void *data);
> -  /* How to initialize symbolizer for the PPID.  */
> -  int (*start_symbolizer) (pid_t ppid);
> -  void (*end_symbolizer) (void);
> -  char *(*symbolize) (void *addr);
> -} pmu_tool_fns;
> -
> -enum pmu_state
> -{
> -  PMU_NONE,             /* Not configurated at all.  */
> -  PMU_INITIALIZED,      /* Configured and initialized.  */
> -  PMU_ERROR,            /* Configuration error. Cannot recover.  */
> -  PMU_ON,               /* Currently profiling.  */
> -  PMU_OFF               /* Currently stopped, but can be restarted.  */
> -};
> -
> -enum cpu_vendor_signature
> -{
> -  CPU_VENDOR_UKNOWN = 0,
> -  CPU_VENDOR_INTEL  = 0x756e6547, /* Genu */
> -  CPU_VENDOR_AMD    = 0x68747541 /* Auth */
> -};
> -
> -/* Info about pmu tool during the run time.  */
> -struct pmu_tool_info
> -{
> -  /* Current pmu tool.  */
> -  enum pmu_tool_type tool;
> -  /* Current event.  */
> -  enum pmu_event_type event;
> -  /* filename for storing the pmu profile.  */
> -  char *pmu_profile_filename;
> -  /* Intermediate file where the tool stores the PMU data.  */
> -  char *raw_pmu_profile_filename;
> -  /* Where PMU tool's stderr should be stored.  */
> -  char *tool_stderr_filename;
> -  enum pmu_state pmu_profiling_state;
> -  enum cpu_vendor_signature cpu_vendor; /* as discovered by cpuid */
> -  pid_t pmu_tool_pid;   /* process id of the pmu tool */
> -  pid_t symbolizer_pid; /* process id of the symbolizer */
> -  int symbolizer_to_pipefd[2]; /* pipe for writing to the symbolizer */
> -  int symbolizer_from_pipefd[2];  /* pipe for reading from the symbolizer */
> -  void *pmu_data;       /* an opaque pointer for the tool to store pmu data */
> -  int verbose;          /* turn on additional debugging */
> -  unsigned top_n_address;  /* how many addresses to symbolize */
> -  pmu_tool_fns *tool_details;  /* list of functions how to start/stop/parse */
> -};
> -
> -/* Global struct for recordkeeping.  */
> -static struct pmu_tool_info *the_pmu_tool_info;
> -
> -/* Additional info is printed if these are non-zero.  */
> -static int tool_debug = 0;
> -static int sym_debug = 0;
> -
> -static int parse_load_latency_line (char *line, gcov_pmu_ll_info_t *ll_info);
> -static int parse_branch_mispredict_line (char *line,
> -                                         gcov_pmu_brm_info_t *brm_info);
>  static unsigned convert_pct_to_unsigned (float pct);
> -static void start_pfmon_module (pid_t ppid, char *tmpfile, const char **pfmon_args);
>  static void *init_pmu_load_latency (void);
>  static void *init_pmu_branch_mispredict (void);
>  static void destroy_load_latency_infos (void *info);
>  static void destroy_branch_mispredict_infos (void *info);
> -static int parse_pfmon_load_latency (char *filename, void *pmu_data);
> -static int parse_pfmon_branch_mispredicts (char *filename, void *pmu_data);
>  static gcov_unsigned_t gcov_tag_pmu_tool_header_length (gcov_pmu_tool_header_t
>                                                          *header);
>  static void gcov_write_tool_header (gcov_pmu_tool_header_t *header);
> @@ -238,456 +80,7 @@ static void gcov_write_branch_mispredict_infos (vo
>  static void gcov_write_ll_line (const gcov_pmu_ll_info_t *ll_info);
>  static void gcov_write_branch_mispredict_line (const gcov_pmu_brm_info_t
>                                                 *brm_info);
> -static int start_addr2line_symbolizer (pid_t pid);
> -static void end_addr2line_symbolizer (void);
> -static char *symbolize_addr2line (void *p);
> -static void reset_symbolizer_parent_pipes (void);
> -static void reset_symbolizer_child_pipes (void);
> -/* parse and cache relevant tool info.  */
> -static int parse_pmu_profile_options (const char *options);
> -static gcov_pmu_tool_header_t *parse_pfmon_tool_header (FILE *fp,
> -                                                        const char *end_header);
>
> -
> -/* How to access the necessary functions for the PMU tools.  */
> -pmu_tool_fns all_pmu_tool_fns[PTT_LAST][PET_LAST] = {
> -  {
> -    {
> -      "intel-load-latency",             /* name */
> -      pfmon_intel_ll_args,              /* tool args */
> -      init_pmu_load_latency,            /* initialization */
> -      start_pfmon_module,               /* start */
> -      0,                                /* stop */
> -      parse_pfmon_load_latency,         /* parse */
> -      gcov_write_load_latency_infos,    /* write */
> -      destroy_load_latency_infos,       /* cleanup */
> -      start_addr2line_symbolizer,       /* start symbolizer */
> -      end_addr2line_symbolizer,         /* end symbolizer */
> -      symbolize_addr2line,              /* symbolize */
> -    },
> -    {
> -      "amd-load-latency",               /* name */
> -      pfmon_amd_ll_args,                /* tool args */
> -      init_pmu_load_latency,            /* initialization */
> -      start_pfmon_module,               /* start */
> -      0,                                /* stop */
> -      parse_pfmon_load_latency,         /* parse */
> -      gcov_write_load_latency_infos,    /* write */
> -      destroy_load_latency_infos,       /* cleanup */
> -      start_addr2line_symbolizer,       /* start symbolizer */
> -      end_addr2line_symbolizer,         /* end symbolizer */
> -      symbolize_addr2line,              /* symbolize */
> -    },
> -    {
> -      "intel-branch-mispredict",        /* name */
> -      pfmon_intel_brm_args,             /* tool args */
> -      init_pmu_branch_mispredict,       /* initialization */
> -      start_pfmon_module,               /* start */
> -      0,                                /* stop */
> -      parse_pfmon_branch_mispredicts,   /* parse */
> -      gcov_write_branch_mispredict_infos,/* write */
> -      destroy_branch_mispredict_infos,  /* cleanup */
> -      start_addr2line_symbolizer,       /* start symbolizer */
> -      end_addr2line_symbolizer,         /* end symbolizer */
> -      symbolize_addr2line,              /* symbolize */
> -    },
> -    {
> -      "amd-branch-mispredict",          /* name */
> -      pfmon_amd_brm_args,               /* tool args */
> -      init_pmu_branch_mispredict,       /* initialization */
> -      start_pfmon_module,               /* start */
> -      0,                                /* stop */
> -      parse_pfmon_branch_mispredicts,   /* parse */
> -      gcov_write_branch_mispredict_infos,/* write */
> -      destroy_branch_mispredict_infos,  /* cleanup */
> -      start_addr2line_symbolizer,       /* start symbolizer */
> -      end_addr2line_symbolizer,         /* end symbolizer */
> -      symbolize_addr2line,              /* symbolize */
> -    }
> -  }
> -};
> -
> -/* Determine the CPU vendor.  Currently only distinguishes x86 based
> -   cpus where the vendor is either Intel or AMD.  Returns one of the
> -   enum cpu_vendor_signatures.  */
> -
> -static unsigned int
> -get_x86cpu_vendor (void)
> -{
> -  unsigned int vendor = CPU_VENDOR_UKNOWN;
> -
> -#if (defined (__x86_64__) || defined (__i386__))
> -  if (__get_cpuid_max (0, &vendor) < 1)
> -    return CPU_VENDOR_UKNOWN;      /* Cannot determine cpu type.  */
> -#endif
> -
> -  if (vendor == CPU_VENDOR_INTEL || vendor == CPU_VENDOR_AMD)
> -    return vendor;
> -  else
> -    return CPU_VENDOR_UKNOWN;
> -}
> -
> -
> -/* Parse PMU tool option string provided on the command line and store
> -   information in global structure.  Return 0 on success, otherwise
> -   return 1.  Any changes to this should be synced with
> -   check_pmu_profile_options() which does compile time check.  */
> -
> -static int
> -parse_pmu_profile_options (const char *options)
> -{
> -  enum pmu_tool_type ptt = the_pmu_tool_info->tool;
> -  enum pmu_event_type pet = PET_LAST;
> -  const char *pmutool_path;
> -  the_pmu_tool_info->cpu_vendor =  get_x86cpu_vendor ();
> -  /* Determine the platform we are running on.  */
> -  if (the_pmu_tool_info->cpu_vendor == CPU_VENDOR_UKNOWN)
> -    {
> -      /* Cpuid failed or uknown vendor.  */
> -      the_pmu_tool_info->pmu_profiling_state = PMU_ERROR;
> -      return 1;
> -    }
> -
> -  /* Validate the options.  */
> -  if (strcmp(options, "load-latency") &&
> -      strcmp(options, "load-latency-verbose") &&
> -      strcmp(options, "branch-mispredict") &&
> -      strcmp(options, "branch-mispredict-verbose"))
> -    return 1;
> -
> -  /* Check if are aksed to collect load latency PMU data.  */
> -  if (!strcmp(options, "load-latency") ||
> -      !strcmp(options, "load-latency-verbose"))
> -    {
> -      if (the_pmu_tool_info->cpu_vendor == CPU_VENDOR_INTEL)
> -        pet = PET_INTEL_LOAD_LATENCY;
> -      else
> -        pet = PET_AMD_LOAD_LATENCY;
> -      if (!strcmp(options, "load-latency-verbose"))
> -        the_pmu_tool_info->verbose = 1;
> -    }
> -
> -  /* Check if are aksed to collect branch mispredict PMU data.  */
> -  if (!strcmp(options, "branch-mispredict") ||
> -      !strcmp(options, "branch-mispredict-verbose"))
> -    {
> -      if (the_pmu_tool_info->cpu_vendor == CPU_VENDOR_INTEL)
> -        pet = PET_INTEL_BRANCH_MISPREDICT;
> -      else
> -        pet = PET_AMD_BRANCH_MISPREDICT;
> -      if (!strcmp(options, "branch-mispredict-verbose"))
> -        the_pmu_tool_info->verbose = 1;
> -    }
> -
> -  the_pmu_tool_info->tool_details = &all_pmu_tool_fns[ptt][pet];
> -  the_pmu_tool_info->event = pet;
> -
> -  /* Allow users to override the default tool path.  */
> -  pmutool_path = getenv ("GCOV_PMUTOOL_PATH");
> -  if (pmutool_path && strlen (pmutool_path))
> -    the_pmu_tool_info->tool_details->arg_array[0] = pmutool_path;
> -
> -  return 0;
> -}
> -
> -/* Do the initialization of addr2line symbolizer for the process id
> -   given by TASK_PID.  It forks an addr2line process and creates two
> -   pipes where addresses can be written and source_filename:line_num
> -   entries can be read.  Returns 0 on success, non-zero otherwise.  */
> -
> -static int
> -start_addr2line_symbolizer (pid_t task_pid)
> -{
> -  pid_t pid;
> -  char *addr2line_path;
> -
> -  /* Allow users to override the default addr2line path.  */
> -  addr2line_path = getenv ("GCOV_ADDR2LINE_PATH");
> -  if (addr2line_path && strlen (addr2line_path))
> -    addr2line_args[0] = addr2line_path;
> -
> -  if (pipe (the_pmu_tool_info->symbolizer_from_pipefd) == -1)
> -    {
> -      fprintf (stderr, "Cannot create symbolizer write pipe.\n");
> -      return 1;
> -    }
> -  if (pipe (the_pmu_tool_info->symbolizer_to_pipefd) == -1)
> -    {
> -      fprintf (stderr, "Cannot create symbolizer read pipe.\n");
> -      return 1;
> -    }
> -
> -  pid = fork ();
> -  if (pid == -1)
> -    {
> -      /* error condition */
> -      fprintf (stderr, "Cannot create symbolizer process.\n");
> -      reset_symbolizer_parent_pipes ();
> -      reset_symbolizer_child_pipes ();
> -      return 1;
> -    }
> -
> -  if (pid == 0)
> -    {
> -      /* child does an exec and then connects to/from the pipe */
> -      unsigned n_args = 0;
> -      char proc_exe_buf[128];
> -      int new_write_fd, new_read_fd;
> -      int i;
> -
> -      /* Go over the current addr2line args.  */
> -      for (i = 0; i < PMU_TOOL_MAX_ARGS && addr2line_args[i]; ++i)
> -        n_args++;
> -
> -      /* We are going to add one more arg for the /proc/pid/exe */
> -      if (n_args >= (PMU_TOOL_MAX_ARGS - 1))
> -        {
> -          fprintf (stderr, "too many addr2line args: %d\n", n_args);
> -          _exit (0);
> -        }
> -      snprintf (proc_exe_buf, sizeof (proc_exe_buf), "/proc/%d/exe",
> -                task_pid);
> -
> -      /* Add the extra arg for the process id.  */
> -      addr2line_args[n_args] = proc_exe_buf;
> -      n_args++;
> -
> -      addr2line_args[n_args] = (const char *)NULL;  /* terminating NULL */
> -
> -      if (sym_debug)
> -        {
> -          fprintf (stderr, "addr2line args:");
> -          for (i = 0; i < PMU_TOOL_MAX_ARGS && addr2line_args[i]; ++i)
> -            fprintf (stderr, " %s", addr2line_args[i]);
> -          fprintf (stderr, "\n");
> -        }
> -
> -      /* Close unused ends of the two pipes.  */
> -      reset_symbolizer_child_pipes ();
> -
> -      /* Connect the pipes to stdin/stdout of the child process.  */
> -      new_read_fd = dup2 (the_pmu_tool_info->symbolizer_to_pipefd[0], 0);
> -      new_write_fd = dup2 (the_pmu_tool_info->symbolizer_from_pipefd[1], 1);
> -      if (new_read_fd == -1 || new_write_fd == -1)
> -        {
> -          fprintf (stderr, "could not dup symbolizer fds\n");
> -          reset_symbolizer_parent_pipes ();
> -          reset_symbolizer_child_pipes ();
> -          _exit (0);
> -        }
> -      the_pmu_tool_info->symbolizer_to_pipefd[0] = new_read_fd;
> -      the_pmu_tool_info->symbolizer_from_pipefd[1] = new_write_fd;
> -
> -      /* Do execve with NULL env. */
> -      execve (addr2line_args[0], (char * const*)addr2line_args,
> -              (char * const*)NULL);
> -      /* exec returned, an error condition.  */
> -      fprintf (stderr, "could not create symbolizer process: %s\n",
> -               addr2line_args[0]);
> -      reset_symbolizer_parent_pipes ();
> -      reset_symbolizer_child_pipes ();
> -      _exit (0);
> -    }
> -  else
> -    {
> -      /* parent */
> -      the_pmu_tool_info->symbolizer_pid = pid;
> -      /* Close unused ends of the two pipes.  */
> -      reset_symbolizer_parent_pipes ();
> -      return 0;
> -    }
> -  return 0;
> -}
> -
> -/* Close unused write end of the from-pipe and read end of the
> -   to-pipe.  */
> -
> -static void
> -reset_symbolizer_parent_pipes (void)
> -{
> -  if (the_pmu_tool_info->symbolizer_from_pipefd[1] != -1)
> -    {
> -      close (the_pmu_tool_info->symbolizer_from_pipefd[1]);
> -      the_pmu_tool_info->symbolizer_from_pipefd[1] = -1;
> -    }
> -  if (the_pmu_tool_info->symbolizer_to_pipefd[0] != -1)
> -    {
> -      close (the_pmu_tool_info->symbolizer_to_pipefd[0]);
> -      the_pmu_tool_info->symbolizer_to_pipefd[0] = -1;
> -    }
> -}
> -
> -/* Close unused write end of the to-pipe and read end of the
> -   from-pipe.  */
> -
> -static void
> -reset_symbolizer_child_pipes (void)
> -{
> -  if (the_pmu_tool_info->symbolizer_to_pipefd[1] != -1)
> -    {
> -      close (the_pmu_tool_info->symbolizer_to_pipefd[1]);
> -      the_pmu_tool_info->symbolizer_to_pipefd[1] = -1;
> -    }
> -  if (the_pmu_tool_info->symbolizer_from_pipefd[0] != -1)
> -    {
> -      close (the_pmu_tool_info->symbolizer_from_pipefd[0]);
> -      the_pmu_tool_info->symbolizer_from_pipefd[0] = -1;
> -    }
> -}
> -
> -
> -/* Perform cleanup for the symbolizer process.  */
> -
> -static void
> -end_addr2line_symbolizer (void)
> -{
> -  int pid_status;
> -  int wait_status;
> -  pid_t pid = the_pmu_tool_info->symbolizer_pid;
> -
> -  /* Symbolizer was not running.  */
> -  if (!pid)
> -    return;
> -
> -  reset_symbolizer_parent_pipes ();
> -  reset_symbolizer_child_pipes ();
> -  kill (pid, SIGTERM);
> -  wait_status = waitpid (pid, &pid_status, 0);
> -  if (sym_debug)
> -  {
> -    if (wait_status == pid)
> -      fprintf (stderr, "Normal exit. symbolizer terminated.\n");
> -    else
> -      fprintf (stderr, "Abnormal exit. symbolizer status, %d.\n", pid_status);
> -  }
> -  the_pmu_tool_info->symbolizer_pid = 0;  /* Symoblizer no longer running.  */
> -}
> -
> -
> -/* Given an address ADDR, return a string containing
> -   source_filename:line_num entries.  */
> -
> -static char *
> -symbolize_addr2line (void *addr)
> -{
> -  char buf[32];  /* holds the ascii version of address */
> -  int write_count;
> -  int read_count;
> -  char *srcfile_linenum;
> -  size_t max_length = 1024;
> -
> -  if (!the_pmu_tool_info->symbolizer_pid)
> -    return default_addr2line;    /* symbolizer is not running */
> -
> -  write_count = snprintf (buf, sizeof (buf), "%p\n", addr);
> -
> -  /* Write the address into the pipe.  */
> -  if (write (the_pmu_tool_info->symbolizer_to_pipefd[1], buf, write_count)
> -      < write_count)
> -    {
> -      if (sym_debug)
> -        fprintf (stderr, "Cannot write symbolizer pipe.\n");
> -      return default_addr2line;
> -    }
> -
> -  srcfile_linenum = XNEWVEC (char, max_length);
> -  read_count = read (the_pmu_tool_info->symbolizer_from_pipefd[0],
> -                     srcfile_linenum, max_length);
> -  if (read_count == -1)
> -    {
> -      if (sym_debug)
> -        fprintf (stderr, "Cannot read symbolizer pipe.\n");
> -      XDELETEVEC (srcfile_linenum);
> -      return default_addr2line;
> -    }
> -
> -  srcfile_linenum[read_count] = 0;
> -  if (sym_debug)
> -    fprintf (stderr, "symbolizer: for address %p, read_count %d, got %s\n",
> -             addr, read_count, srcfile_linenum);
> -  return srcfile_linenum;
> -}
> -
> -/* Start monitoring PPID process via pfmon tool using TMPFILE as a
> -   file to store the raw data and using PFMON_ARGS as the command line
> -   arguments.  */
> -
> -static void
> -start_pfmon_module (pid_t ppid, char *tmpfile, const char **pfmon_args)
> -{
> -  int i;
> -  unsigned int n_args = 0;
> -  unsigned n_chars;
> -  char pid_buf[64];
> -  char filename_buf[1024];
> -  char top_n_buf[24];
> -  unsigned extra_args;
> -
> -  /* Go over the current pfmon args */
> -  for (i = 0; i < PMU_TOOL_MAX_ARGS && pfmon_args[i]; ++i)
> -    n_args++;
> -
> -  if (the_pmu_tool_info->verbose)
> -    extra_args = 4; /* account for additional --verbose */
> -  else
> -    extra_args = 3;
> -
> -  /* We are going to add args.  */
> -  if (n_args >= (PMU_TOOL_MAX_ARGS - extra_args))
> -    {
> -      fprintf (stderr, "too many pfmon args: %d\n", n_args);
> -      _exit (0);
> -    }
> -
> -  n_chars = snprintf (pid_buf, sizeof (pid_buf), "--attach-task=%ld",
> -                      (long)ppid);
> -  if (n_chars >= sizeof (pid_buf))
> -    {
> -      fprintf (stderr, "pfmon task id too long: %s\n", pid_buf);
> -      return;
> -    }
> -  pfmon_args[n_args] = pid_buf;
> -  n_args++;
> -
> -  n_chars = snprintf (filename_buf, sizeof (filename_buf), "--smpl-outfile=%s",
> -                      tmpfile);
> -  if (n_chars >= sizeof (filename_buf))
> -    {
> -      fprintf (stderr, "pfmon filename too long: %s\n", filename_buf);
> -      return;
> -    }
> -  pfmon_args[n_args] = filename_buf;
> -  n_args++;
> -
> -  n_chars = snprintf (top_n_buf, sizeof (top_n_buf), "--smpl-show-top=%d",
> -                      the_pmu_tool_info->top_n_address);
> -  if (n_chars >= sizeof (top_n_buf))
> -    {
> -      fprintf (stderr, "pfmon option too long: %s\n", top_n_buf);
> -      return;
> -    }
> -  pfmon_args[n_args] = top_n_buf;
> -  n_args++;
> -
> -  if (the_pmu_tool_info->verbose) {
> -    /* Add --verbose as well.  */
> -    pfmon_args[n_args] = "--verbose";
> -    n_args++;
> -  }
> -  pfmon_args[n_args] = (char *)NULL;
> -
> -  if (tool_debug)
> -    {
> -      fprintf (stderr, "pfmon args:");
> -      for (i = 0; i < PMU_TOOL_MAX_ARGS && pfmon_args[i]; ++i)
> -        fprintf (stderr, " %s", pfmon_args[i]);
> -      fprintf (stderr, "\n");
> -    }
> -  /* Do execve with NULL env.  */
> -  execve (pfmon_args[0], (char *const *)pfmon_args, (char * const*)NULL);
> -  /* does not return */
> -}
> -
>  /* Convert a fractional PCT to an unsigned integer after
>     muliplying by 100.  */
>
> @@ -697,147 +90,6 @@ convert_pct_to_unsigned (float pct)
>    return (unsigned)(pct * 100.0f);
>  }
>
> -/* Parse the load latency info pointed by LINE and save it into
> -   LL_INFO. Returns 0 if the line was parsed successfully, non-zero
> -   otherwise.
> -
> -   An example header+line look like these:
> -   "counts   %self    %cum     <10     <32     <64    <256   <1024  >=1024
> -   %wself          code addr symbol"
> -   "218  24.06%  24.06% 100.00%   0.00%   0.00%   0.00%   0.00%   0.00%  22.70%
> -   0x0000000000413e75 CalcSSIM(...)+965</tmp/psnr>"
> -*/
> -
> -static int
> -parse_load_latency_line (char *line, gcov_pmu_ll_info_t *ll_info)
> -{
> -  unsigned counts;
> -  /* These are percentages parsed as floats, but then converted to
> -     integers after multiplying by 100.  */
> -  float self, cum, lt_10, lt_32, lt_64, lt_256, lt_1024, gt_1024, wself;
> -  long unsigned int p;
> -  int n_values;
> -  pmu_tool_fns *tool_details = the_pmu_tool_info->tool_details;
> -
> -  n_values = sscanf (line, "%u%f%%%f%%%f%%%f%%%f%%%f%%%f%%%f%%%f%%%lx",
> -                     &counts, &self, &cum, &lt_10, &lt_32, &lt_64, &lt_256,
> -                     &lt_1024, &gt_1024, &wself, &p);
> -  if (n_values != 11)
> -    return 1;
> -
> -  /* Values read successfully. Do the assignment after converting
> -   * percentages into ints.  */
> -  ll_info->counts = counts;
> -  ll_info->self = convert_pct_to_unsigned (self);
> -  ll_info->cum = convert_pct_to_unsigned (cum);
> -  ll_info->lt_10 = convert_pct_to_unsigned (lt_10);
> -  ll_info->lt_32 = convert_pct_to_unsigned (lt_32);
> -  ll_info->lt_64 = convert_pct_to_unsigned (lt_64);
> -  ll_info->lt_256 = convert_pct_to_unsigned (lt_256);
> -  ll_info->lt_1024 = convert_pct_to_unsigned (lt_1024);
> -  ll_info->gt_1024 = convert_pct_to_unsigned (gt_1024);
> -  ll_info->wself = convert_pct_to_unsigned (wself);
> -  ll_info->code_addr = p;
> -
> -  /* Run the raw address through the symbolizer.  */
> -  if (tool_details->symbolize)
> -    {
> -      char *sym_info = tool_details->symbolize ((void *)p);
> -      /* sym_info is of the form src_filename:linenum.  Descriminator is
> -         currently not supported by addr2line.  */
> -      char *sep = strchr (sym_info, ':');
> -      if (!sep)
> -        {
> -          /* Assume entire string is srcfile.  */
> -          ll_info->filename = (char *)sym_info;
> -          ll_info->line = 0;
> -        }
> -      else
> -        {
> -          /* Terminate the filename string at the separator.  */
> -          *sep = 0;
> -          ll_info->filename = (char *)sym_info;
> -          /* Convert rest of the sym info to a line number.  */
> -          ll_info->line = atol (sep+1);
> -        }
> -      ll_info->discriminator = 0;
> -    }
> -  else
> -    {
> -      /* No symbolizer available.  */
> -      ll_info->filename = NULL;
> -      ll_info->line = 0;
> -      ll_info->discriminator = 0;
> -    }
> -  return 0;
> -}
> -
> -/* Parse the branch mispredict info pointed by LINE and save it into
> -   BRM_INFO. Returns 0 if the line was parsed successfully, non-zero
> -   otherwise.
> -
> -   An example header+line look like these:
> -   "counts   %self    %cum          code addr symbol"
> -   "6869  37.67%  37.67% 0x00000000004007e5 sum(std::vector<int*,
> -    std::allocator<int*> > const&)+51</root/tmp/array>"
> -*/
> -
> -static int
> -parse_branch_mispredict_line (char *line, gcov_pmu_brm_info_t *brm_info)
> -{
> -  unsigned counts;
> -  /* These are percentages parsed as floats, but then converted to
> -     ints after multiplying by 100.  */
> -  float self, cum;
> -  long unsigned int p;
> -  int n_values;
> -  pmu_tool_fns *tool_details = the_pmu_tool_info->tool_details;
> -
> -  n_values = sscanf (line, "%u%f%%%f%%%lx",
> -                     &counts, &self, &cum, &p);
> -  if (n_values != 4)
> -    return 1;
> -
> -  /* Values read successfully. Do the assignment after converting
> -   * percentages into ints.  */
> -  brm_info->counts = counts;
> -  brm_info->self = convert_pct_to_unsigned (self);
> -  brm_info->cum = convert_pct_to_unsigned (cum);
> -  brm_info->code_addr = p;
> -
> -  /* Run the raw address through the symbolizer.  */
> -  if (tool_details->symbolize)
> -    {
> -      char *sym_info = tool_details->symbolize ((void *)p);
> -      /* sym_info is of the form src_filename:linenum.  Descriminator is
> -         currently not supported by addr2line.  */
> -      char *sep = strchr (sym_info, ':');
> -      if (!sep)
> -        {
> -          /* Assume entire string is srcfile.  */
> -          brm_info->filename = sym_info;
> -          brm_info->line = 0;
> -        }
> -      else
> -        {
> -          /* Terminate the filename string at the separator.  */
> -          *sep = 0;
> -          brm_info->filename = sym_info;
> -          /* Convert rest of the sym info to a line number.  */
> -          brm_info->line = atol (sep+1);
> -        }
> -      brm_info->discriminator = 0;
> -    }
> -  else
> -    {
> -      /* No symbolizer available.  */
> -      brm_info->filename = NULL;
> -      brm_info->line = 0;
> -      brm_info->discriminator = 0;
> -    }
> -  return 0;
> -}
> -
>  /* Delete load latency info structures INFO.  */
>
>  static void
> @@ -876,309 +128,6 @@ destroy_branch_mispredict_infos (void *info)
>    brm_infos->brm_count = 0;
>  }
>
> -/* Parse FILENAME for load latency lines into a structure
> -   PMU_DATA. Returns 0 on on success.  Returns non-zero on
> -   failure.  */
> -
> -static int
> -parse_pfmon_load_latency (char *filename, void *pmu_data)
> -{
> -  FILE *fp;
> -  size_t buflen = 2*1024;
> -  char *buf;
> -  ll_infos_t *load_latency_infos = (ll_infos_t *)pmu_data;
> -  gcov_pmu_tool_header_t *tool_header = 0;
> -
> -  if ((fp = fopen (filename, "r")) == NULL)
> -    {
> -      fprintf (stderr, "cannot open pmu data file: %s\n", filename);
> -      return 1;
> -    }
> -
> -  if (!(tool_header = parse_pfmon_tool_header (fp, pfmon_ll_header)))
> -    {
> -      fprintf (stderr, "cannot parse pmu data file header: %s\n", filename);
> -      return 1;
> -    }
> -
> -  buf = XNEWVEC (char, buflen);
> -  while (fgets (buf, buflen, fp))
> -    {
> -      gcov_pmu_ll_info_t *ll_info = XNEW (gcov_pmu_ll_info_t);
> -      if (!parse_load_latency_line (buf, ll_info))
> -        {
> -          /* valid line, add to the array */
> -          load_latency_infos->ll_count++;
> -          if (load_latency_infos->ll_count >=
> -              load_latency_infos->alloc_ll_count)
> -            {
> -              /* need to realloc */
> -              load_latency_infos->ll_array =
> -                realloc (load_latency_infos->ll_array,
> -                         2 * load_latency_infos->alloc_ll_count);
> -              if (load_latency_infos->ll_array == NULL)
> -                {
> -                  fprintf (stderr, "Cannot allocate load latency memory.\n");
> -                  __destroy_pmu_tool_header (tool_header);
> -                  free (buf);
> -                  fclose (fp);
> -                  return 1;
> -                }
> -            }
> -          load_latency_infos->ll_array[load_latency_infos->ll_count - 1] =
> -            ll_info;
> -        }
> -      else
> -        /* Delete invalid line.  */
> -        XDELETE (ll_info);
> -    }
> -  free (buf);
> -  fclose (fp);
> -  load_latency_infos->pmu_tool_header = tool_header;
> -  return 0;
> -}
> -
> -/* Parse open file FP until END_HEADER is seen. The data matching
> -   gcov_pmu_tool_header_t fields is saved and returned in a new
> -   struct. In case of failure, it returns NULL.  */
> -
> -static gcov_pmu_tool_header_t *
> -parse_pfmon_tool_header (FILE *fp, const char *end_header)
> -{
> -  static const char tag_hostname[] = "# hostname: ";
> -  static const char tag_kversion[] = "# kernel version: ";
> -  static const char tag_hostcpu[] = "# host CPUs:  ";
> -  static const char tag_column_desc_start[] = "# description of columns:";
> -  static const char tag_column_desc_end[] =
> -      "#       other columns are self-explanatory";
> -  size_t buflen = 4*1024;
> -  char *buf, *buf_start, *buf_end;
> -  gcov_pmu_tool_header_t *tool_header = XNEWVEC (gcov_pmu_tool_header_t, 1);
> -  char *hostname = 0;
> -  char *kversion = 0;
> -  char *hostcpu = 0;
> -  char *column_description = 0;
> -  char *column_desc_start = 0;
> -  char *column_desc_end = 0;
> -  const char *column_header = 0;
> -  int got_hostname = 0;
> -  int got_kversion = 0 ;
> -  int got_hostcpu = 0;
> -  int got_end_header = 0;
> -  int got_column_description = 0;
> -
> -  buf = XNEWVEC (char, buflen);
> -  buf_start = buf;
> -  buf_end = buf + buflen;
> -  while (buf < (buf_end - 1) && fgets (buf, buf_end - buf, fp))
> -    {
> -      if (strncmp (end_header, buf, buf_end - buf) == 0)
> -      {
> -        got_end_header = 1;
> -        break;
> -      }
> -      if (!got_hostname &&
> -          strncmp (buf, tag_hostname, strlen (tag_hostname)) == 0)
> -        {
> -          size_t len = strlen (buf) - strlen (tag_hostname);
> -          hostname = XNEWVEC (char, len);
> -          memcpy (hostname, buf + strlen (tag_hostname), len);
> -          hostname[len - 1] = 0;
> -          tool_header->hostname = hostname;
> -          got_hostname = 1;
> -        }
> -
> -      if (!got_kversion &&
> -          strncmp (buf, tag_kversion, strlen (tag_kversion)) == 0)
> -        {
> -          size_t len = strlen (buf) - strlen (tag_kversion);
> -          kversion = XNEWVEC (char, len);
> -          memcpy (kversion, buf + strlen (tag_kversion), len);
> -          kversion[len - 1] = 0;
> -          tool_header->kernel_version = kversion;
> -          got_kversion = 1;
> -        }
> -
> -      if (!got_hostcpu &&
> -          strncmp (buf, tag_hostcpu, strlen (tag_hostcpu)) == 0)
> -        {
> -          size_t len = strlen (buf) - strlen (tag_hostcpu);
> -          hostcpu = XNEWVEC (char, len);
> -          memcpy (hostcpu, buf + strlen (tag_hostcpu), len);
> -          hostcpu[len - 1] = 0;
> -          tool_header->host_cpu = hostcpu;
> -          got_hostcpu = 1;
> -        }
> -      if (!got_column_description &&
> -          strncmp (buf, tag_column_desc_start, strlen (tag_column_desc_start))
> -          == 0)
> -        {
> -          column_desc_start = buf;
> -          column_desc_end = 0;
> -          /* Continue reading until end of the column descriptor.  */
> -          while (buf < (buf_end - 1) && fgets (buf, buf_end - buf, fp))
> -            {
> -              if (strncmp (buf, tag_column_desc_end,
> -                           strlen (tag_column_desc_end)) == 0)
> -                {
> -                  column_desc_end = buf + strlen (tag_column_desc_end);
> -                  break;
> -                }
> -              buf += strlen (buf);
> -            }
> -          if (column_desc_end)
> -            {
> -              /* Found the end, copy it into a new string.  */
> -              column_description = XNEWVEC (char, column_desc_end -
> -                                            column_desc_start + 1);
> -              got_column_description = 1;
> -              strcpy (column_description, column_desc_start);
> -              tool_header->column_description = column_description;
> -            }
> -        }
> -      buf += strlen (buf);
> -    }
> -
> -  /* If we are missing any of the fields, return NULL.  */
> -  if (!got_end_header || !got_hostname || !got_kversion || !got_hostcpu
> -      || !got_column_description)
> -    {
> -      free (hostname);
> -      free (kversion);
> -      free (hostcpu);
> -      free (column_description);
> -      free (buf_start);
> -      free (tool_header);
> -      return NULL;
> -    }
> -
> -  switch (the_pmu_tool_info->event)
> -    {
> -    case PET_INTEL_LOAD_LATENCY:
> -    case PET_AMD_LOAD_LATENCY:
> -      column_header = pfmon_ll_header;
> -      break;
> -    case PET_INTEL_BRANCH_MISPREDICT:
> -    case PET_AMD_BRANCH_MISPREDICT:
> -      column_header = pfmon_bm_header;
> -      break;
> -    default:
> -      break;
> -    }
> -  tool_header->column_header = strdup (column_header);
> -  tool_header->full_header = buf_start;
> -  return tool_header;
> -}
> -
> -
> -/* Parse FILENAME for branch mispredict lines into a structure
> -   PMU_DATA. Returns 0 on on success.  Returns non-zero on
> -   failure.  */
> -
> -static int
> -parse_pfmon_branch_mispredicts (char *filename, void *pmu_data)
> -{
> -  FILE *fp;
> -  size_t buflen = 2*1024;
> -  char *buf;
> -  brm_infos_t *brm_infos = (brm_infos_t *)pmu_data;
> -  gcov_pmu_tool_header_t *tool_header = 0;
> -
> -  if ((fp = fopen (filename, "r")) == NULL)
> -    {
> -      fprintf (stderr, "cannot open pmu data file: %s\n", filename);
> -      return 1;
> -    }
> -
> -  if (!(tool_header = parse_pfmon_tool_header (fp, pfmon_bm_header)))
> -    {
> -      fprintf (stderr, "cannot parse pmu data file header: %s\n", filename);
> -      return 1;
> -    }
> -
> -  buf = XNEWVEC (char, buflen);
> -  while (fgets (buf, buflen, fp))
> -    {
> -      gcov_pmu_brm_info_t *brm = XNEW (gcov_pmu_brm_info_t);
> -      if (!parse_branch_mispredict_line (buf, brm))
> -        {
> -          /* Valid line, add to the array.  */
> -          brm_infos->brm_count++;
> -          if (brm_infos->brm_count >= brm_infos->alloc_brm_count)
> -            {
> -              /* Do we need to realloc? */
> -              brm_infos->brm_array =
> -                realloc (brm_infos->brm_array,
> -                         2 * brm_infos->alloc_brm_count);
> -              if (brm_infos->brm_array == NULL) {
> -                fprintf (stderr,
> -                         "Cannot allocate memory for br mispredicts.\n");
> -                __destroy_pmu_tool_header (tool_header);
> -                free (buf);
> -                fclose (fp);
> -                return 1;
> -              }
> -            }
> -          brm_infos->brm_array[brm_infos->brm_count - 1] = brm;
> -        }
> -      else
> -        /* Delete invalid line.  */
> -        XDELETE (brm);
> -    }
> -  free (buf);
> -  fclose (fp);
> -  brm_infos->pmu_tool_header = tool_header;
> -  return 0;
> -}
> -
> -/* Start the monitoring process using pmu tool. Return 0 on success,
> -   non-zero otherwise.  */
> -
> -static int
> -pmu_start (void)
> -{
> -  pid_t pid;
> -
> -  /* no start function */
> -  if (!the_pmu_tool_info->tool_details->start_pmu_module)
> -    return 1;
> -
> -  pid = fork ();
> -  if (pid == -1)
> -    {
> -      /* error condition */
> -      fprintf (stderr, "Cannot create PMU profiling process, exiting.\n");
> -      return 1;
> -    }
> -  else if (pid == 0)
> -    {
> -      /* child */
> -      pid_t ppid = getppid();
> -      char *tmpfile = the_pmu_tool_info->raw_pmu_profile_filename;
> -      const char **pfmon_args = the_pmu_tool_info->tool_details->arg_array;
> -      int new_stderr_fd;
> -
> -      /* Redirect stderr from the child process into a separate file.  */
> -      new_stderr_fd = creat (the_pmu_tool_info->tool_stderr_filename,
> -                             S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
> -      if (new_stderr_fd != -1)
> -          dup2 (new_stderr_fd, 2);
> -      /* The following does an exec and thus is not expected to return.  */
> -      the_pmu_tool_info->tool_details->start_pmu_module(ppid, tmpfile,
> -                                                        pfmon_args);
> -      /* exec returned, an error condition.  */
> -      fprintf (stderr, "could not create profiling process: %s\n",
> -               the_pmu_tool_info->tool_details->arg_array[0]);
> -      _exit (0);
> -    }
> -  else
> -    {
> -      /* parent */
> -      the_pmu_tool_info->pmu_tool_pid = pid;
> -      return 0;
> -    }
> -}
> -
>  /* Allocate and initialize pmu load latency structure.  */
>
>  static void *
> @@ -1205,160 +154,6 @@ init_pmu_branch_mispredict (void)
>    return (void *)brm_info;
>  }
>
> -/* Initialize pmu tool based upon PMU_INFO. Sets the appropriate tool
> -   type in the global the_pmu_tool_info.  */
> -
> -static int
> -init_pmu_tool (struct gcov_pmu_info *pmu_info)
> -{
> -  the_pmu_tool_info->pmu_profiling_state = PMU_NONE;
> -  the_pmu_tool_info->verbose = 0;
> -  the_pmu_tool_info->tool = PTT_PFMON;  /* we support only pfmon */
> -  the_pmu_tool_info->pmu_tool_pid = 0;
> -  the_pmu_tool_info->top_n_address = pmu_info->pmu_top_n_address;
> -  the_pmu_tool_info->symbolizer_pid = 0;
> -  the_pmu_tool_info->symbolizer_to_pipefd[0] = -1;
> -  the_pmu_tool_info->symbolizer_to_pipefd[1] = -1;
> -  the_pmu_tool_info->symbolizer_from_pipefd[0] = -1;
> -  the_pmu_tool_info->symbolizer_from_pipefd[1] = -1;
> -
> -  if (parse_pmu_profile_options (pmu_info->pmu_tool))
> -    return 1;
> -
> -  if (the_pmu_tool_info->pmu_profiling_state == PMU_ERROR)
> -    {
> -      fprintf (stderr, "Unsupported PMU module: %s, disabling PMU profiling.\n",
> -               pmu_info->pmu_tool);
> -      return 1;
> -    }
> -
> -  if (the_pmu_tool_info->tool_details->init_pmu_module)
> -    /* initialize module */
> -    the_pmu_tool_info->pmu_data =
> -      the_pmu_tool_info->tool_details->init_pmu_module();
> -  return 0;
> -}
> -
> -/* Initialize PMU profiling based upon the information passed in
> -   PMU_INFO and use pmu_profile_filename as the file to store the PMU
> -   profile.  This is called multiple times from libgcov, once per
> -   object file.  We need to make sure to do the necessary
> -   initialization only the first time.  For subsequent invocations it
> -   behaves as a NOOP.  */
> -
> -void
> -__gcov_init_pmu_profiler (struct gcov_pmu_info *pmu_info)
> -{
> -  char *raw_pmu_profile_filename;
> -  char *tool_stderr_filename;
> -  if (!pmu_info || !pmu_info->pmu_profile_filename || !pmu_info->pmu_tool)
> -    return;
> -
> -  /* Allocate the global structure on first invocation.  */
> -  if (!the_pmu_tool_info)
> -    {
> -      the_pmu_tool_info = XNEWVEC (struct pmu_tool_info, 1);
> -      if (!the_pmu_tool_info)
> -        {
> -          fprintf (stderr, "Error allocating memory for PMU tool\n");
> -          return;
> -        }
> -      if (init_pmu_tool (pmu_info))
> -        {
> -          /* Initialization error.  */
> -          XDELETE (the_pmu_tool_info);
> -          the_pmu_tool_info = 0;
> -          return;
> -        }
> -    }
> -
> -  switch (the_pmu_tool_info->pmu_profiling_state)
> -    {
> -    case PMU_NONE:
> -      the_pmu_tool_info->pmu_profile_filename =
> -        strdup (pmu_info->pmu_profile_filename);
> -      /* Construct an intermediate filename by substituting trailing
> -         '.gcda' with '.pmud'.  */
> -      raw_pmu_profile_filename = strdup (pmu_info->pmu_profile_filename);
> -      if (raw_pmu_profile_filename == NULL)
> -        {
> -          fprintf (stderr, "Cannot allocate memory\n");
> -          exit (1);
> -        }
> -      strcpy (raw_pmu_profile_filename + strlen (raw_pmu_profile_filename) - 4,
> -              "pmud");
> -
> -      /* Construct a filename for collecting PMU tool's stderr by
> -         substituting trailing '.gcda' with '.stderr'.  */
> -      tool_stderr_filename =
> -        XNEWVEC (char, strlen (pmu_info->pmu_profile_filename) + 1 + 2);
> -      strcpy (tool_stderr_filename, pmu_info->pmu_profile_filename);
> -      strcpy (tool_stderr_filename + strlen (tool_stderr_filename) - 4,
> -              "stderr");
> -      the_pmu_tool_info->raw_pmu_profile_filename = raw_pmu_profile_filename;
> -      the_pmu_tool_info->tool_stderr_filename = tool_stderr_filename;
> -      the_pmu_tool_info->pmu_profiling_state = PMU_INITIALIZED;
> -      break;
> -
> -    case PMU_INITIALIZED:
> -    case PMU_OFF:
> -    case PMU_ON:
> -    case PMU_ERROR:
> -      break;
> -    default:
> -      break;
> -    }
> -}
> -
> -/* Start PMU profiling.  It updates the current state.  */
> -
> -void
> -__gcov_start_pmu_profiler (void)
> -{
> -  if (!the_pmu_tool_info)
> -    return;
> -
> -  switch (the_pmu_tool_info->pmu_profiling_state)
> -    {
> -    case PMU_INITIALIZED:
> -      if (!pmu_start ())
> -        the_pmu_tool_info->pmu_profiling_state = PMU_ON;
> -      else
> -        the_pmu_tool_info->pmu_profiling_state = PMU_ERROR;
> -      break;
> -
> -    case PMU_NONE:
> -      /* PMU was not properly initialized, don't attempt start it.  */
> -      the_pmu_tool_info->pmu_profiling_state = PMU_ERROR;
> -      break;
> -
> -    case PMU_OFF:
> -      /* Restarting PMU is not yet supported.  */
> -    case PMU_ON:
> -      /* Do nothing.  */
> -    case PMU_ERROR:
> -      break;
> -
> -    default:
> -      break;
> -    }
> -}
> -
> -/* Stop PMU profiling.  Currently it doesn't do anything except
> -   bookkeeping.  */
> -
> -void
> -__gcov_stop_pmu_profiler (void)
> -{
> -  if (!the_pmu_tool_info)
> -    return;
> -
> -  if (the_pmu_tool_info->tool_details->stop_pmu_module)
> -    the_pmu_tool_info->tool_details->stop_pmu_module();
> -  if (the_pmu_tool_info->pmu_profiling_state == PMU_ON)
> -    the_pmu_tool_info->pmu_profiling_state = PMU_OFF;
> -}
> -
>  /* Write the load latency information LL_INFO into the gcda file.  */
>
>  static void
> @@ -1400,55 +195,6 @@ gcov_write_branch_mispredict_line (const gcov_pmu_
>    gcov_write_string (brm_info->filename);
>  }
>
> -/* Write load latency information INFO into the gcda file.  The gcda
> -   file has already been opened and is available for writing.  */
> -
> -static void
> -gcov_write_load_latency_infos (void *info)
> -{
> -  unsigned i;
> -  const ll_infos_t *ll_infos = (const ll_infos_t *)info;
> -  gcov_unsigned_t stamp = 0;  /* Don't use stamp as we don't support merge.  */
> -  /* We don't support merge, and instead always rewrite the file.  But
> -     to rewrite a gcov file we must first read it, however the read
> -     value is ignored.  */
> -  gcov_read_unsigned ();
> -  gcov_rewrite ();
> -  gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
> -  gcov_write_unsigned (stamp);
> -  if (ll_infos->pmu_tool_header)
> -    gcov_write_tool_header (ll_infos->pmu_tool_header);
> -  for (i = 0; i < ll_infos->ll_count; ++i)
> -    {
> -      /* Write each line.  */
> -      gcov_write_ll_line (ll_infos->ll_array[i]);
> -    }
> -  gcov_truncate ();
> -}
> -
> -/* Write branch mispredict information INFO into the gcda file.  The
> -   gcda file has already been opened and is available for writing.  */
> -
> -static void
> -gcov_write_branch_mispredict_infos (void *info)
> -{
> -  unsigned i;
> -  const brm_infos_t *brm_infos = (const brm_infos_t *)info;
> -  gcov_unsigned_t stamp = 0;  /* Don't use stamp as we don't support merge. */
> -  /* We don't support merge, and instead always rewrite the file.  */
> -  gcov_rewrite ();
> -  gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
> -  gcov_write_unsigned (stamp);
> -  if (brm_infos->pmu_tool_header)
> -    gcov_write_tool_header (brm_infos->pmu_tool_header);
> -  for (i = 0; i < brm_infos->brm_count; ++i)
> -    {
> -      /* Write each line.  */
> -      gcov_write_branch_mispredict_line (brm_infos->brm_array[i]);
> -    }
> -  gcov_truncate ();
> -}
> -
>  /* Compute TOOL_HEADER length for writing into the gcov file.  */
>
>  static gcov_unsigned_t
> @@ -1483,70 +229,4 @@ gcov_write_tool_header (gcov_pmu_tool_header_t *he
>    gcov_write_string (header->full_header);
>  }
>
> -
> -/* End PMU profiling. If GCDA_ERROR is non-zero then write profiling data into
> -   already open gcda file */
> -
> -void
> -__gcov_end_pmu_profiler (int gcda_error)
> -{
> -  int pid_status;
> -  int wait_status;
> -  pid_t pid;
> -  pmu_tool_fns *tool_details;
> -
> -  if (!the_pmu_tool_info)
> -    return;
> -
> -  tool_details = the_pmu_tool_info->tool_details;
> -  pid = the_pmu_tool_info->pmu_tool_pid;
> -  if (pid)
> -    {
> -      if (tool_debug)
> -        fprintf (stderr, "terminating PMU profiling process %ld\n", (long)pid);
> -      kill (pid, SIGTERM);
> -      if (tool_debug)
> -        fprintf (stderr, "parent: waiting for pmu process to end\n");
> -      wait_status = waitpid (pid, &pid_status, 0);
> -      if (tool_debug) {
> -        if (wait_status == pid)
> -          fprintf (stderr, "Normal exit. Child terminated.\n");
> -        else
> -          fprintf (stderr, "Abnormal exit. child status, %d.\n", pid_status);
> -      }
> -    }
> -
> -  if (the_pmu_tool_info->pmu_profiling_state != PMU_OFF)
> -    {
> -      /* nothing to do */
> -      fprintf (stderr,
> -               "__gcov_dump_pmu_profile: incorrect pmu state: %d, pid: %ld\n",
> -               the_pmu_tool_info->pmu_profiling_state,
> -               (unsigned long)pid);
> -      return;
> -    }
> -
> -  if (!tool_details->parse_pmu_output)
> -    return;
> -
> -  /* Since we are going to parse the output, we also need symbolizer.  */
> -  if (tool_details->start_symbolizer)
> -    tool_details->start_symbolizer (getpid ());
> -
> -  if (!tool_details->parse_pmu_output
> -      (the_pmu_tool_info->raw_pmu_profile_filename,
> -       the_pmu_tool_info->pmu_data))
> -    {
> -      if (!gcda_error && tool_details->gcov_write_pmu_data)
> -        /* Write tool output into the gcda file.  */
> -        tool_details->gcov_write_pmu_data (the_pmu_tool_info->pmu_data);
> -    }
> -
> -  if (tool_details->end_symbolizer)
> -    tool_details->end_symbolizer ();
> -
> -  if (tool_details->cleanup_pmu_data)
> -    tool_details->cleanup_pmu_data (the_pmu_tool_info->pmu_data);
> -}
> -
>  #endif
> Index: libgcc/libgcov.c
> ===================================================================
> --- libgcc/libgcov.c    (revision 190135)
> +++ libgcc/libgcov.c    (working copy)
> @@ -463,37 +463,6 @@ gcov_alloc_filename (void)
>    gi_filename_up = gi_filename + prefix_length;
>  }
>
> -/* Stop the pmu profiler and dump pmu profile info into the global file.  */
> -
> -static void
> -pmu_profile_stop (void)
> -{
> -  const char *pmu_profile_filename =  __gcov_pmu_profile_filename;
> -  const char *pmu_options = __gcov_pmu_profile_options;
> -  size_t filename_length;
> -  int gcda_error;
> -
> -  if (!pmu_profile_filename || !pmu_options)
> -    return;
> -
> -  __gcov_stop_pmu_profiler ();
> -
> -  filename_length = strlen (pmu_profile_filename);
> -  if (filename_length > gcov_max_filename)
> -    gcov_max_filename = filename_length;
> -  /* Allocate and initialize the filename scratch space.  */
> -  gcov_alloc_filename ();
> -  GCOV_GET_FILENAME (prefix_length, gcov_prefix_strip, pmu_profile_filename,
> -                     gi_filename_up);
> -  /* Open the gcda file for writing. We don't support merge yet.  */
> -  gcda_error = gcov_open_by_filename (gi_filename);
> -  __gcov_end_pmu_profiler (gcda_error);
> -  if ((gcda_error = gcov_close ()))
> -    gcov_error (gcda_error  < 0 ?  "pmu_profile_stop:%s:Overflow writing\n" :
> -                "pmu_profile_stop:%s:Error writing\n",
> -                gi_filename);
> -}
> -
>  /* Sort N entries in VALUE_ARRAY in descending order.
>     Each entry in VALUE_ARRAY has two values. The sorting
>     is based on the second value.  */
> @@ -634,9 +603,6 @@ gcov_exit (void)
>    if (gcov_dump_complete)
>      return;
>
> -  /* Stop and write the PMU profile data into the global file.  */
> -  pmu_profile_stop ();
> -
>    dump_module_info = gcov_exit_init ();
>
>    for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
> @@ -701,25 +667,11 @@ __gcov_init (struct gcov_info *info)
>      {
>        const char *ptr = info->filename;
>        size_t filename_length = strlen (info->filename);
> -      struct gcov_pmu_info pmu_info;
>
>        /* Refresh the longest file name information.  */
>        if (filename_length > gcov_max_filename)
>          gcov_max_filename = filename_length;
>
> -      /* Initialize the pmu profiler.  */
> -      pmu_info.pmu_profile_filename = __gcov_pmu_profile_filename;
> -      pmu_info.pmu_tool = __gcov_pmu_profile_options;
> -      pmu_info.pmu_top_n_address = __gcov_pmu_top_n_address;
> -      __gcov_init_pmu_profiler (&pmu_info);
> -      if (pmu_info.pmu_profile_filename)
> -        {
> -          /* Refresh the longest file name information.  */
> -          filename_length = strlen (pmu_info.pmu_profile_filename);
> -          if (filename_length > gcov_max_filename)
> -            gcov_max_filename = filename_length;
> -        }
> -
>        /* Assign the module ID (starting at 1).  */
>        info->mod_info->ident = (++gcov_cur_module_id);
>        gcc_assert (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (GEN_FUNC_GLOBAL_ID (
> @@ -729,8 +681,6 @@ __gcov_init (struct gcov_info *info)
>        if (!__gcov_list)
>          {
>            atexit (gcov_exit);
> -          /* Start pmu profiler. */
> -          __gcov_start_pmu_profiler ();
>          }
>
>        info->next = __gcov_list;
> @@ -746,10 +696,8 @@ __gcov_init (struct gcov_info *info)
>  void
>  __gcov_flush (void)
>  {
> -  __gcov_stop_pmu_profiler ();
>    gcov_exit ();
>    gcov_clear ();
> -  __gcov_start_pmu_profiler ();
>  }
>
>  #else /* __GCOV_KERNEL__ */
>
> --
> This patch is available for review at http://codereview.appspot.com/6442086
diff mbox

Patch

Index: libgcc/pmu-profile.c
===================================================================
--- libgcc/pmu-profile.c	(revision 190135)
+++ libgcc/pmu-profile.c	(working copy)
@@ -67,169 +67,11 @@  see the files COPYING3 and COPYING.RUNTIME respect
 #define XDELETEVEC(p) free(p)
 #define XDELETE(p) free(p)
 
-#define PFMON_CMD "/usr/bin/pfmon"
-#define ADDR2LINE_CMD "/usr/bin/addr2line"
-#define PMU_TOOL_MAX_ARGS (20)
-static char default_addr2line[] = "??:0";
-static const char pfmon_ll_header[] = "#     counts   %self    %cum     "
-    "<10     <32     <64    <256   <1024  >=1024  %wself          "
-    "code addr symbol\n";
-static const char pfmon_bm_header[] =
-    "#     counts   %self    %cum          code addr symbol\n";
-
-const char *pfmon_intel_ll_args[PMU_TOOL_MAX_ARGS] = {
-  PFMON_CMD,
-  "--aggregate-results",
-  "--follow-all",
-  "--with-header",
-  "--smpl-module=pebs-ll",
-  "--ld-lat-threshold=4",
-  "--pebs-ll-dcmiss-code",
-  "--resolve-addresses",
-  "-emem_inst_retired:LATENCY_ABOVE_THRESHOLD",
-  "--long-smpl-periods=10000",
-  0  /* terminating NULL must be present */
-};
-
-const char *pfmon_amd_ll_args[PMU_TOOL_MAX_ARGS] = {
-  PFMON_CMD,
-  "--aggregate-results",
-  "--follow-all",
-  "-uk",
-  "--with-header",
-  "--smpl-module=ibs",
-  "--resolve-addresses",
-  "-eibsop_event:uops",
-  "--ibs-dcmiss-code",
-  "--long-smpl-periods=0xffff0",
-  0  /* terminating NULL must be present */
-};
-
-const char *pfmon_intel_brm_args[PMU_TOOL_MAX_ARGS] = {
-  PFMON_CMD,
-  "--aggregate-results",
-  "--follow-all",
-  "--with-header",
-  "--resolve-addresses",
-  "-eMISPREDICTED_BRANCH_RETIRED",
-  "--long-smpl-periods=10000",
-  0  /* terminating NULL must be present */
-};
-
-const char *pfmon_amd_brm_args[PMU_TOOL_MAX_ARGS] = {
-  PFMON_CMD,
-  "--aggregate-results",
-  "--follow-all",
-  "--with-header",
-  "--resolve-addresses",
-  "-eRETIRED_MISPREDICTED_BRANCH_INSTRUCTIONS",
-  "--long-smpl-periods=10000",
-  0  /* terminating NULL must be present */
-};
-
-const char *addr2line_args[PMU_TOOL_MAX_ARGS] = {
-  ADDR2LINE_CMD,
-  "-e",
-  0  /* terminating NULL must be present */
-};
-
-
-enum pmu_tool_type
-{
-  PTT_PFMON,
-  PTT_LAST
-};
-
-enum pmu_event_type
-{
-  PET_INTEL_LOAD_LATENCY,
-  PET_AMD_LOAD_LATENCY,
-  PET_INTEL_BRANCH_MISPREDICT,
-  PET_AMD_BRANCH_MISPREDICT,
-  PET_LAST
-};
-
-typedef struct pmu_tool_fns {
-  const char *name;     /* name of the pmu tool */
-  /* pmu tool commandline argument.  */
-  const char **arg_array;
-  /* Initialize pmu module.  */
-  void *(*init_pmu_module) (void);
-  /* Start profililing.  */
-  void (*start_pmu_module) (pid_t ppid, char *tmpfile, const char **args);
-  /* Stop profililing.  */
-  void (*stop_pmu_module) (void);
-  /* How to parse the output generated by the PMU tool.  */
-  int (*parse_pmu_output) (char *filename, void *pmu_data);
-  /* How to write parsed pmu data into gcda file.  */
-  void (*gcov_write_pmu_data) (void *data);
-  /* How to cleanup any data structure created during parsing.  */
-  void (*cleanup_pmu_data) (void *data);
-  /* How to initialize symbolizer for the PPID.  */
-  int (*start_symbolizer) (pid_t ppid);
-  void (*end_symbolizer) (void);
-  char *(*symbolize) (void *addr);
-} pmu_tool_fns;
-
-enum pmu_state
-{
-  PMU_NONE,             /* Not configurated at all.  */
-  PMU_INITIALIZED,      /* Configured and initialized.  */
-  PMU_ERROR,            /* Configuration error. Cannot recover.  */
-  PMU_ON,               /* Currently profiling.  */
-  PMU_OFF               /* Currently stopped, but can be restarted.  */
-};
-
-enum cpu_vendor_signature
-{
-  CPU_VENDOR_UKNOWN = 0,
-  CPU_VENDOR_INTEL  = 0x756e6547, /* Genu */
-  CPU_VENDOR_AMD    = 0x68747541 /* Auth */
-};
-
-/* Info about pmu tool during the run time.  */
-struct pmu_tool_info
-{
-  /* Current pmu tool.  */
-  enum pmu_tool_type tool;
-  /* Current event.  */
-  enum pmu_event_type event;
-  /* filename for storing the pmu profile.  */
-  char *pmu_profile_filename;
-  /* Intermediate file where the tool stores the PMU data.  */
-  char *raw_pmu_profile_filename;
-  /* Where PMU tool's stderr should be stored.  */
-  char *tool_stderr_filename;
-  enum pmu_state pmu_profiling_state;
-  enum cpu_vendor_signature cpu_vendor; /* as discovered by cpuid */
-  pid_t pmu_tool_pid;   /* process id of the pmu tool */
-  pid_t symbolizer_pid; /* process id of the symbolizer */
-  int symbolizer_to_pipefd[2]; /* pipe for writing to the symbolizer */
-  int symbolizer_from_pipefd[2];  /* pipe for reading from the symbolizer */
-  void *pmu_data;       /* an opaque pointer for the tool to store pmu data */
-  int verbose;          /* turn on additional debugging */
-  unsigned top_n_address;  /* how many addresses to symbolize */
-  pmu_tool_fns *tool_details;  /* list of functions how to start/stop/parse */
-};
-
-/* Global struct for recordkeeping.  */
-static struct pmu_tool_info *the_pmu_tool_info;
-
-/* Additional info is printed if these are non-zero.  */
-static int tool_debug = 0;
-static int sym_debug = 0;
-
-static int parse_load_latency_line (char *line, gcov_pmu_ll_info_t *ll_info);
-static int parse_branch_mispredict_line (char *line,
-                                         gcov_pmu_brm_info_t *brm_info);
 static unsigned convert_pct_to_unsigned (float pct);
-static void start_pfmon_module (pid_t ppid, char *tmpfile, const char **pfmon_args);
 static void *init_pmu_load_latency (void);
 static void *init_pmu_branch_mispredict (void);
 static void destroy_load_latency_infos (void *info);
 static void destroy_branch_mispredict_infos (void *info);
-static int parse_pfmon_load_latency (char *filename, void *pmu_data);
-static int parse_pfmon_branch_mispredicts (char *filename, void *pmu_data);
 static gcov_unsigned_t gcov_tag_pmu_tool_header_length (gcov_pmu_tool_header_t
                                                         *header);
 static void gcov_write_tool_header (gcov_pmu_tool_header_t *header);
@@ -238,456 +80,7 @@  static void gcov_write_branch_mispredict_infos (vo
 static void gcov_write_ll_line (const gcov_pmu_ll_info_t *ll_info);
 static void gcov_write_branch_mispredict_line (const gcov_pmu_brm_info_t
                                                *brm_info);
-static int start_addr2line_symbolizer (pid_t pid);
-static void end_addr2line_symbolizer (void);
-static char *symbolize_addr2line (void *p);
-static void reset_symbolizer_parent_pipes (void);
-static void reset_symbolizer_child_pipes (void);
-/* parse and cache relevant tool info.  */
-static int parse_pmu_profile_options (const char *options);
-static gcov_pmu_tool_header_t *parse_pfmon_tool_header (FILE *fp,
-                                                        const char *end_header);
 
-
-/* How to access the necessary functions for the PMU tools.  */
-pmu_tool_fns all_pmu_tool_fns[PTT_LAST][PET_LAST] = {
-  {
-    {
-      "intel-load-latency",             /* name */
-      pfmon_intel_ll_args,              /* tool args */
-      init_pmu_load_latency,            /* initialization */
-      start_pfmon_module,               /* start */
-      0,                                /* stop */
-      parse_pfmon_load_latency,         /* parse */
-      gcov_write_load_latency_infos,    /* write */
-      destroy_load_latency_infos,       /* cleanup */
-      start_addr2line_symbolizer,       /* start symbolizer */
-      end_addr2line_symbolizer,         /* end symbolizer */
-      symbolize_addr2line,              /* symbolize */
-    },
-    {
-      "amd-load-latency",               /* name */
-      pfmon_amd_ll_args,                /* tool args */
-      init_pmu_load_latency,            /* initialization */
-      start_pfmon_module,               /* start */
-      0,                                /* stop */
-      parse_pfmon_load_latency,         /* parse */
-      gcov_write_load_latency_infos,    /* write */
-      destroy_load_latency_infos,       /* cleanup */
-      start_addr2line_symbolizer,       /* start symbolizer */
-      end_addr2line_symbolizer,         /* end symbolizer */
-      symbolize_addr2line,              /* symbolize */
-    },
-    {
-      "intel-branch-mispredict",        /* name */
-      pfmon_intel_brm_args,             /* tool args */
-      init_pmu_branch_mispredict,       /* initialization */
-      start_pfmon_module,               /* start */
-      0,                                /* stop */
-      parse_pfmon_branch_mispredicts,   /* parse */
-      gcov_write_branch_mispredict_infos,/* write */
-      destroy_branch_mispredict_infos,  /* cleanup */
-      start_addr2line_symbolizer,       /* start symbolizer */
-      end_addr2line_symbolizer,         /* end symbolizer */
-      symbolize_addr2line,              /* symbolize */
-    },
-    {
-      "amd-branch-mispredict",          /* name */
-      pfmon_amd_brm_args,               /* tool args */
-      init_pmu_branch_mispredict,       /* initialization */
-      start_pfmon_module,               /* start */
-      0,                                /* stop */
-      parse_pfmon_branch_mispredicts,   /* parse */
-      gcov_write_branch_mispredict_infos,/* write */
-      destroy_branch_mispredict_infos,  /* cleanup */
-      start_addr2line_symbolizer,       /* start symbolizer */
-      end_addr2line_symbolizer,         /* end symbolizer */
-      symbolize_addr2line,              /* symbolize */
-    }
-  }
-};
-
-/* Determine the CPU vendor.  Currently only distinguishes x86 based
-   cpus where the vendor is either Intel or AMD.  Returns one of the
-   enum cpu_vendor_signatures.  */
-
-static unsigned int
-get_x86cpu_vendor (void)
-{
-  unsigned int vendor = CPU_VENDOR_UKNOWN;
-
-#if (defined (__x86_64__) || defined (__i386__))
-  if (__get_cpuid_max (0, &vendor) < 1)
-    return CPU_VENDOR_UKNOWN;      /* Cannot determine cpu type.  */
-#endif
-
-  if (vendor == CPU_VENDOR_INTEL || vendor == CPU_VENDOR_AMD)
-    return vendor;
-  else
-    return CPU_VENDOR_UKNOWN;
-}
-
-
-/* Parse PMU tool option string provided on the command line and store
-   information in global structure.  Return 0 on success, otherwise
-   return 1.  Any changes to this should be synced with
-   check_pmu_profile_options() which does compile time check.  */
-
-static int
-parse_pmu_profile_options (const char *options)
-{
-  enum pmu_tool_type ptt = the_pmu_tool_info->tool;
-  enum pmu_event_type pet = PET_LAST;
-  const char *pmutool_path;
-  the_pmu_tool_info->cpu_vendor =  get_x86cpu_vendor ();
-  /* Determine the platform we are running on.  */
-  if (the_pmu_tool_info->cpu_vendor == CPU_VENDOR_UKNOWN)
-    {
-      /* Cpuid failed or uknown vendor.  */
-      the_pmu_tool_info->pmu_profiling_state = PMU_ERROR;
-      return 1;
-    }
-
-  /* Validate the options.  */
-  if (strcmp(options, "load-latency") &&
-      strcmp(options, "load-latency-verbose") &&
-      strcmp(options, "branch-mispredict") &&
-      strcmp(options, "branch-mispredict-verbose"))
-    return 1;
-
-  /* Check if are aksed to collect load latency PMU data.  */
-  if (!strcmp(options, "load-latency") ||
-      !strcmp(options, "load-latency-verbose"))
-    {
-      if (the_pmu_tool_info->cpu_vendor == CPU_VENDOR_INTEL)
-        pet = PET_INTEL_LOAD_LATENCY;
-      else
-        pet = PET_AMD_LOAD_LATENCY;
-      if (!strcmp(options, "load-latency-verbose"))
-        the_pmu_tool_info->verbose = 1;
-    }
-
-  /* Check if are aksed to collect branch mispredict PMU data.  */
-  if (!strcmp(options, "branch-mispredict") ||
-      !strcmp(options, "branch-mispredict-verbose"))
-    {
-      if (the_pmu_tool_info->cpu_vendor == CPU_VENDOR_INTEL)
-        pet = PET_INTEL_BRANCH_MISPREDICT;
-      else
-        pet = PET_AMD_BRANCH_MISPREDICT;
-      if (!strcmp(options, "branch-mispredict-verbose"))
-        the_pmu_tool_info->verbose = 1;
-    }
-
-  the_pmu_tool_info->tool_details = &all_pmu_tool_fns[ptt][pet];
-  the_pmu_tool_info->event = pet;
-
-  /* Allow users to override the default tool path.  */
-  pmutool_path = getenv ("GCOV_PMUTOOL_PATH");
-  if (pmutool_path && strlen (pmutool_path))
-    the_pmu_tool_info->tool_details->arg_array[0] = pmutool_path;
-
-  return 0;
-}
-
-/* Do the initialization of addr2line symbolizer for the process id
-   given by TASK_PID.  It forks an addr2line process and creates two
-   pipes where addresses can be written and source_filename:line_num
-   entries can be read.  Returns 0 on success, non-zero otherwise.  */
-
-static int
-start_addr2line_symbolizer (pid_t task_pid)
-{
-  pid_t pid;
-  char *addr2line_path;
-
-  /* Allow users to override the default addr2line path.  */
-  addr2line_path = getenv ("GCOV_ADDR2LINE_PATH");
-  if (addr2line_path && strlen (addr2line_path))
-    addr2line_args[0] = addr2line_path;
-
-  if (pipe (the_pmu_tool_info->symbolizer_from_pipefd) == -1)
-    {
-      fprintf (stderr, "Cannot create symbolizer write pipe.\n");
-      return 1;
-    }
-  if (pipe (the_pmu_tool_info->symbolizer_to_pipefd) == -1)
-    {
-      fprintf (stderr, "Cannot create symbolizer read pipe.\n");
-      return 1;
-    }
-
-  pid = fork ();
-  if (pid == -1)
-    {
-      /* error condition */
-      fprintf (stderr, "Cannot create symbolizer process.\n");
-      reset_symbolizer_parent_pipes ();
-      reset_symbolizer_child_pipes ();
-      return 1;
-    }
-
-  if (pid == 0)
-    {
-      /* child does an exec and then connects to/from the pipe */
-      unsigned n_args = 0;
-      char proc_exe_buf[128];
-      int new_write_fd, new_read_fd;
-      int i;
-
-      /* Go over the current addr2line args.  */
-      for (i = 0; i < PMU_TOOL_MAX_ARGS && addr2line_args[i]; ++i)
-        n_args++;
-
-      /* We are going to add one more arg for the /proc/pid/exe */
-      if (n_args >= (PMU_TOOL_MAX_ARGS - 1))
-        {
-          fprintf (stderr, "too many addr2line args: %d\n", n_args);
-          _exit (0);
-        }
-      snprintf (proc_exe_buf, sizeof (proc_exe_buf), "/proc/%d/exe",
-                task_pid);
-
-      /* Add the extra arg for the process id.  */
-      addr2line_args[n_args] = proc_exe_buf;
-      n_args++;
-
-      addr2line_args[n_args] = (const char *)NULL;  /* terminating NULL */
-
-      if (sym_debug)
-        {
-          fprintf (stderr, "addr2line args:");
-          for (i = 0; i < PMU_TOOL_MAX_ARGS && addr2line_args[i]; ++i)
-            fprintf (stderr, " %s", addr2line_args[i]);
-          fprintf (stderr, "\n");
-        }
-
-      /* Close unused ends of the two pipes.  */
-      reset_symbolizer_child_pipes ();
-
-      /* Connect the pipes to stdin/stdout of the child process.  */
-      new_read_fd = dup2 (the_pmu_tool_info->symbolizer_to_pipefd[0], 0);
-      new_write_fd = dup2 (the_pmu_tool_info->symbolizer_from_pipefd[1], 1);
-      if (new_read_fd == -1 || new_write_fd == -1)
-        {
-          fprintf (stderr, "could not dup symbolizer fds\n");
-          reset_symbolizer_parent_pipes ();
-          reset_symbolizer_child_pipes ();
-          _exit (0);
-        }
-      the_pmu_tool_info->symbolizer_to_pipefd[0] = new_read_fd;
-      the_pmu_tool_info->symbolizer_from_pipefd[1] = new_write_fd;
-
-      /* Do execve with NULL env. */
-      execve (addr2line_args[0], (char * const*)addr2line_args,
-              (char * const*)NULL);
-      /* exec returned, an error condition.  */
-      fprintf (stderr, "could not create symbolizer process: %s\n",
-               addr2line_args[0]);
-      reset_symbolizer_parent_pipes ();
-      reset_symbolizer_child_pipes ();
-      _exit (0);
-    }
-  else
-    {
-      /* parent */
-      the_pmu_tool_info->symbolizer_pid = pid;
-      /* Close unused ends of the two pipes.  */
-      reset_symbolizer_parent_pipes ();
-      return 0;
-    }
-  return 0;
-}
-
-/* Close unused write end of the from-pipe and read end of the
-   to-pipe.  */
-
-static void
-reset_symbolizer_parent_pipes (void)
-{
-  if (the_pmu_tool_info->symbolizer_from_pipefd[1] != -1)
-    {
-      close (the_pmu_tool_info->symbolizer_from_pipefd[1]);
-      the_pmu_tool_info->symbolizer_from_pipefd[1] = -1;
-    }
-  if (the_pmu_tool_info->symbolizer_to_pipefd[0] != -1)
-    {
-      close (the_pmu_tool_info->symbolizer_to_pipefd[0]);
-      the_pmu_tool_info->symbolizer_to_pipefd[0] = -1;
-    }
-}
-
-/* Close unused write end of the to-pipe and read end of the
-   from-pipe.  */
-
-static void
-reset_symbolizer_child_pipes (void)
-{
-  if (the_pmu_tool_info->symbolizer_to_pipefd[1] != -1)
-    {
-      close (the_pmu_tool_info->symbolizer_to_pipefd[1]);
-      the_pmu_tool_info->symbolizer_to_pipefd[1] = -1;
-    }
-  if (the_pmu_tool_info->symbolizer_from_pipefd[0] != -1)
-    {
-      close (the_pmu_tool_info->symbolizer_from_pipefd[0]);
-      the_pmu_tool_info->symbolizer_from_pipefd[0] = -1;
-    }
-}
-
-
-/* Perform cleanup for the symbolizer process.  */
-
-static void
-end_addr2line_symbolizer (void)
-{
-  int pid_status;
-  int wait_status;
-  pid_t pid = the_pmu_tool_info->symbolizer_pid;
-
-  /* Symbolizer was not running.  */
-  if (!pid)
-    return;
-
-  reset_symbolizer_parent_pipes ();
-  reset_symbolizer_child_pipes ();
-  kill (pid, SIGTERM);
-  wait_status = waitpid (pid, &pid_status, 0);
-  if (sym_debug)
-  {
-    if (wait_status == pid)
-      fprintf (stderr, "Normal exit. symbolizer terminated.\n");
-    else
-      fprintf (stderr, "Abnormal exit. symbolizer status, %d.\n", pid_status);
-  }
-  the_pmu_tool_info->symbolizer_pid = 0;  /* Symoblizer no longer running.  */
-}
-
-
-/* Given an address ADDR, return a string containing
-   source_filename:line_num entries.  */
-
-static char *
-symbolize_addr2line (void *addr)
-{
-  char buf[32];  /* holds the ascii version of address */
-  int write_count;
-  int read_count;
-  char *srcfile_linenum;
-  size_t max_length = 1024;
-
-  if (!the_pmu_tool_info->symbolizer_pid)
-    return default_addr2line;    /* symbolizer is not running */
-
-  write_count = snprintf (buf, sizeof (buf), "%p\n", addr);
-
-  /* Write the address into the pipe.  */
-  if (write (the_pmu_tool_info->symbolizer_to_pipefd[1], buf, write_count)
-      < write_count)
-    {
-      if (sym_debug)
-        fprintf (stderr, "Cannot write symbolizer pipe.\n");
-      return default_addr2line;
-    }
-
-  srcfile_linenum = XNEWVEC (char, max_length);
-  read_count = read (the_pmu_tool_info->symbolizer_from_pipefd[0],
-                     srcfile_linenum, max_length);
-  if (read_count == -1)
-    {
-      if (sym_debug)
-        fprintf (stderr, "Cannot read symbolizer pipe.\n");
-      XDELETEVEC (srcfile_linenum);
-      return default_addr2line;
-    }
-
-  srcfile_linenum[read_count] = 0;
-  if (sym_debug)
-    fprintf (stderr, "symbolizer: for address %p, read_count %d, got %s\n",
-             addr, read_count, srcfile_linenum);
-  return srcfile_linenum;
-}
-
-/* Start monitoring PPID process via pfmon tool using TMPFILE as a
-   file to store the raw data and using PFMON_ARGS as the command line
-   arguments.  */
-
-static void
-start_pfmon_module (pid_t ppid, char *tmpfile, const char **pfmon_args)
-{
-  int i;
-  unsigned int n_args = 0;
-  unsigned n_chars;
-  char pid_buf[64];
-  char filename_buf[1024];
-  char top_n_buf[24];
-  unsigned extra_args;
-
-  /* Go over the current pfmon args */
-  for (i = 0; i < PMU_TOOL_MAX_ARGS && pfmon_args[i]; ++i)
-    n_args++;
-
-  if (the_pmu_tool_info->verbose)
-    extra_args = 4; /* account for additional --verbose */
-  else
-    extra_args = 3;
-
-  /* We are going to add args.  */
-  if (n_args >= (PMU_TOOL_MAX_ARGS - extra_args))
-    {
-      fprintf (stderr, "too many pfmon args: %d\n", n_args);
-      _exit (0);
-    }
-
-  n_chars = snprintf (pid_buf, sizeof (pid_buf), "--attach-task=%ld",
-                      (long)ppid);
-  if (n_chars >= sizeof (pid_buf))
-    {
-      fprintf (stderr, "pfmon task id too long: %s\n", pid_buf);
-      return;
-    }
-  pfmon_args[n_args] = pid_buf;
-  n_args++;
-
-  n_chars = snprintf (filename_buf, sizeof (filename_buf), "--smpl-outfile=%s",
-                      tmpfile);
-  if (n_chars >= sizeof (filename_buf))
-    {
-      fprintf (stderr, "pfmon filename too long: %s\n", filename_buf);
-      return;
-    }
-  pfmon_args[n_args] = filename_buf;
-  n_args++;
-
-  n_chars = snprintf (top_n_buf, sizeof (top_n_buf), "--smpl-show-top=%d",
-                      the_pmu_tool_info->top_n_address);
-  if (n_chars >= sizeof (top_n_buf))
-    {
-      fprintf (stderr, "pfmon option too long: %s\n", top_n_buf);
-      return;
-    }
-  pfmon_args[n_args] = top_n_buf;
-  n_args++;
-
-  if (the_pmu_tool_info->verbose) {
-    /* Add --verbose as well.  */
-    pfmon_args[n_args] = "--verbose";
-    n_args++;
-  }
-  pfmon_args[n_args] = (char *)NULL;
-
-  if (tool_debug)
-    {
-      fprintf (stderr, "pfmon args:");
-      for (i = 0; i < PMU_TOOL_MAX_ARGS && pfmon_args[i]; ++i)
-        fprintf (stderr, " %s", pfmon_args[i]);
-      fprintf (stderr, "\n");
-    }
-  /* Do execve with NULL env.  */
-  execve (pfmon_args[0], (char *const *)pfmon_args, (char * const*)NULL);
-  /* does not return */
-}
-
 /* Convert a fractional PCT to an unsigned integer after
    muliplying by 100.  */
 
@@ -697,147 +90,6 @@  convert_pct_to_unsigned (float pct)
   return (unsigned)(pct * 100.0f);
 }
 
-/* Parse the load latency info pointed by LINE and save it into
-   LL_INFO. Returns 0 if the line was parsed successfully, non-zero
-   otherwise.
-
-   An example header+line look like these:
-   "counts   %self    %cum     <10     <32     <64    <256   <1024  >=1024
-   %wself          code addr symbol"
-   "218  24.06%  24.06% 100.00%   0.00%   0.00%   0.00%   0.00%   0.00%  22.70%
-   0x0000000000413e75 CalcSSIM(...)+965</tmp/psnr>"
-*/
-
-static int
-parse_load_latency_line (char *line, gcov_pmu_ll_info_t *ll_info)
-{
-  unsigned counts;
-  /* These are percentages parsed as floats, but then converted to
-     integers after multiplying by 100.  */
-  float self, cum, lt_10, lt_32, lt_64, lt_256, lt_1024, gt_1024, wself;
-  long unsigned int p;
-  int n_values;
-  pmu_tool_fns *tool_details = the_pmu_tool_info->tool_details;
-
-  n_values = sscanf (line, "%u%f%%%f%%%f%%%f%%%f%%%f%%%f%%%f%%%f%%%lx",
-                     &counts, &self, &cum, &lt_10, &lt_32, &lt_64, &lt_256,
-                     &lt_1024, &gt_1024, &wself, &p);
-  if (n_values != 11)
-    return 1;
-
-  /* Values read successfully. Do the assignment after converting
-   * percentages into ints.  */
-  ll_info->counts = counts;
-  ll_info->self = convert_pct_to_unsigned (self);
-  ll_info->cum = convert_pct_to_unsigned (cum);
-  ll_info->lt_10 = convert_pct_to_unsigned (lt_10);
-  ll_info->lt_32 = convert_pct_to_unsigned (lt_32);
-  ll_info->lt_64 = convert_pct_to_unsigned (lt_64);
-  ll_info->lt_256 = convert_pct_to_unsigned (lt_256);
-  ll_info->lt_1024 = convert_pct_to_unsigned (lt_1024);
-  ll_info->gt_1024 = convert_pct_to_unsigned (gt_1024);
-  ll_info->wself = convert_pct_to_unsigned (wself);
-  ll_info->code_addr = p;
-
-  /* Run the raw address through the symbolizer.  */
-  if (tool_details->symbolize)
-    {
-      char *sym_info = tool_details->symbolize ((void *)p);
-      /* sym_info is of the form src_filename:linenum.  Descriminator is
-         currently not supported by addr2line.  */
-      char *sep = strchr (sym_info, ':');
-      if (!sep)
-        {
-          /* Assume entire string is srcfile.  */
-          ll_info->filename = (char *)sym_info;
-          ll_info->line = 0;
-        }
-      else
-        {
-          /* Terminate the filename string at the separator.  */
-          *sep = 0;
-          ll_info->filename = (char *)sym_info;
-          /* Convert rest of the sym info to a line number.  */
-          ll_info->line = atol (sep+1);
-        }
-      ll_info->discriminator = 0;
-    }
-  else
-    {
-      /* No symbolizer available.  */
-      ll_info->filename = NULL;
-      ll_info->line = 0;
-      ll_info->discriminator = 0;
-    }
-  return 0;
-}
-
-/* Parse the branch mispredict info pointed by LINE and save it into
-   BRM_INFO. Returns 0 if the line was parsed successfully, non-zero
-   otherwise.
-
-   An example header+line look like these:
-   "counts   %self    %cum          code addr symbol"
-   "6869  37.67%  37.67% 0x00000000004007e5 sum(std::vector<int*,
-    std::allocator<int*> > const&)+51</root/tmp/array>"
-*/
-
-static int
-parse_branch_mispredict_line (char *line, gcov_pmu_brm_info_t *brm_info)
-{
-  unsigned counts;
-  /* These are percentages parsed as floats, but then converted to
-     ints after multiplying by 100.  */
-  float self, cum;
-  long unsigned int p;
-  int n_values;
-  pmu_tool_fns *tool_details = the_pmu_tool_info->tool_details;
-
-  n_values = sscanf (line, "%u%f%%%f%%%lx",
-                     &counts, &self, &cum, &p);
-  if (n_values != 4)
-    return 1;
-
-  /* Values read successfully. Do the assignment after converting
-   * percentages into ints.  */
-  brm_info->counts = counts;
-  brm_info->self = convert_pct_to_unsigned (self);
-  brm_info->cum = convert_pct_to_unsigned (cum);
-  brm_info->code_addr = p;
-
-  /* Run the raw address through the symbolizer.  */
-  if (tool_details->symbolize)
-    {
-      char *sym_info = tool_details->symbolize ((void *)p);
-      /* sym_info is of the form src_filename:linenum.  Descriminator is
-         currently not supported by addr2line.  */
-      char *sep = strchr (sym_info, ':');
-      if (!sep)
-        {
-          /* Assume entire string is srcfile.  */
-          brm_info->filename = sym_info;
-          brm_info->line = 0;
-        }
-      else
-        {
-          /* Terminate the filename string at the separator.  */
-          *sep = 0;
-          brm_info->filename = sym_info;
-          /* Convert rest of the sym info to a line number.  */
-          brm_info->line = atol (sep+1);
-        }
-      brm_info->discriminator = 0;
-    }
-  else
-    {
-      /* No symbolizer available.  */
-      brm_info->filename = NULL;
-      brm_info->line = 0;
-      brm_info->discriminator = 0;
-    }
-  return 0;
-}
-
 /* Delete load latency info structures INFO.  */
 
 static void
@@ -876,309 +128,6 @@  destroy_branch_mispredict_infos (void *info)
   brm_infos->brm_count = 0;
 }
 
-/* Parse FILENAME for load latency lines into a structure
-   PMU_DATA. Returns 0 on on success.  Returns non-zero on
-   failure.  */
-
-static int
-parse_pfmon_load_latency (char *filename, void *pmu_data)
-{
-  FILE *fp;
-  size_t buflen = 2*1024;
-  char *buf;
-  ll_infos_t *load_latency_infos = (ll_infos_t *)pmu_data;
-  gcov_pmu_tool_header_t *tool_header = 0;
-
-  if ((fp = fopen (filename, "r")) == NULL)
-    {
-      fprintf (stderr, "cannot open pmu data file: %s\n", filename);
-      return 1;
-    }
-
-  if (!(tool_header = parse_pfmon_tool_header (fp, pfmon_ll_header)))
-    {
-      fprintf (stderr, "cannot parse pmu data file header: %s\n", filename);
-      return 1;
-    }
-
-  buf = XNEWVEC (char, buflen);
-  while (fgets (buf, buflen, fp))
-    {
-      gcov_pmu_ll_info_t *ll_info = XNEW (gcov_pmu_ll_info_t);
-      if (!parse_load_latency_line (buf, ll_info))
-        {
-          /* valid line, add to the array */
-          load_latency_infos->ll_count++;
-          if (load_latency_infos->ll_count >=
-              load_latency_infos->alloc_ll_count)
-            {
-              /* need to realloc */
-              load_latency_infos->ll_array =
-                realloc (load_latency_infos->ll_array,
-                         2 * load_latency_infos->alloc_ll_count);
-              if (load_latency_infos->ll_array == NULL)
-                {
-                  fprintf (stderr, "Cannot allocate load latency memory.\n");
-                  __destroy_pmu_tool_header (tool_header);
-                  free (buf);
-                  fclose (fp);
-                  return 1;
-                }
-            }
-          load_latency_infos->ll_array[load_latency_infos->ll_count - 1] =
-            ll_info;
-        }
-      else
-        /* Delete invalid line.  */
-        XDELETE (ll_info);
-    }
-  free (buf);
-  fclose (fp);
-  load_latency_infos->pmu_tool_header = tool_header;
-  return 0;
-}
-
-/* Parse open file FP until END_HEADER is seen. The data matching
-   gcov_pmu_tool_header_t fields is saved and returned in a new
-   struct. In case of failure, it returns NULL.  */
-
-static gcov_pmu_tool_header_t *
-parse_pfmon_tool_header (FILE *fp, const char *end_header)
-{
-  static const char tag_hostname[] = "# hostname: ";
-  static const char tag_kversion[] = "# kernel version: ";
-  static const char tag_hostcpu[] = "# host CPUs:  ";
-  static const char tag_column_desc_start[] = "# description of columns:";
-  static const char tag_column_desc_end[] =
-      "#	other columns are self-explanatory";
-  size_t buflen = 4*1024;
-  char *buf, *buf_start, *buf_end;
-  gcov_pmu_tool_header_t *tool_header = XNEWVEC (gcov_pmu_tool_header_t, 1);
-  char *hostname = 0;
-  char *kversion = 0;
-  char *hostcpu = 0;
-  char *column_description = 0;
-  char *column_desc_start = 0;
-  char *column_desc_end = 0;
-  const char *column_header = 0;
-  int got_hostname = 0;
-  int got_kversion = 0 ;
-  int got_hostcpu = 0;
-  int got_end_header = 0;
-  int got_column_description = 0;
-
-  buf = XNEWVEC (char, buflen);
-  buf_start = buf;
-  buf_end = buf + buflen;
-  while (buf < (buf_end - 1) && fgets (buf, buf_end - buf, fp))
-    {
-      if (strncmp (end_header, buf, buf_end - buf) == 0)
-      {
-        got_end_header = 1;
-        break;
-      }
-      if (!got_hostname &&
-          strncmp (buf, tag_hostname, strlen (tag_hostname)) == 0)
-        {
-          size_t len = strlen (buf) - strlen (tag_hostname);
-          hostname = XNEWVEC (char, len);
-          memcpy (hostname, buf + strlen (tag_hostname), len);
-          hostname[len - 1] = 0;
-          tool_header->hostname = hostname;
-          got_hostname = 1;
-        }
-
-      if (!got_kversion &&
-          strncmp (buf, tag_kversion, strlen (tag_kversion)) == 0)
-        {
-          size_t len = strlen (buf) - strlen (tag_kversion);
-          kversion = XNEWVEC (char, len);
-          memcpy (kversion, buf + strlen (tag_kversion), len);
-          kversion[len - 1] = 0;
-          tool_header->kernel_version = kversion;
-          got_kversion = 1;
-        }
-
-      if (!got_hostcpu &&
-          strncmp (buf, tag_hostcpu, strlen (tag_hostcpu)) == 0)
-        {
-          size_t len = strlen (buf) - strlen (tag_hostcpu);
-          hostcpu = XNEWVEC (char, len);
-          memcpy (hostcpu, buf + strlen (tag_hostcpu), len);
-          hostcpu[len - 1] = 0;
-          tool_header->host_cpu = hostcpu;
-          got_hostcpu = 1;
-        }
-      if (!got_column_description &&
-          strncmp (buf, tag_column_desc_start, strlen (tag_column_desc_start))
-          == 0)
-        {
-          column_desc_start = buf;
-          column_desc_end = 0;
-          /* Continue reading until end of the column descriptor.  */
-          while (buf < (buf_end - 1) && fgets (buf, buf_end - buf, fp))
-            {
-              if (strncmp (buf, tag_column_desc_end,
-                           strlen (tag_column_desc_end)) == 0)
-                {
-                  column_desc_end = buf + strlen (tag_column_desc_end);
-                  break;
-                }
-              buf += strlen (buf);
-            }
-          if (column_desc_end)
-            {
-              /* Found the end, copy it into a new string.  */
-              column_description = XNEWVEC (char, column_desc_end -
-                                            column_desc_start + 1);
-              got_column_description = 1;
-              strcpy (column_description, column_desc_start);
-              tool_header->column_description = column_description;
-            }
-        }
-      buf += strlen (buf);
-    }
-
-  /* If we are missing any of the fields, return NULL.  */
-  if (!got_end_header || !got_hostname || !got_kversion || !got_hostcpu
-      || !got_column_description)
-    {
-      free (hostname);
-      free (kversion);
-      free (hostcpu);
-      free (column_description);
-      free (buf_start);
-      free (tool_header);
-      return NULL;
-    }
-
-  switch (the_pmu_tool_info->event)
-    {
-    case PET_INTEL_LOAD_LATENCY:
-    case PET_AMD_LOAD_LATENCY:
-      column_header = pfmon_ll_header;
-      break;
-    case PET_INTEL_BRANCH_MISPREDICT:
-    case PET_AMD_BRANCH_MISPREDICT:
-      column_header = pfmon_bm_header;
-      break;
-    default:
-      break;
-    }
-  tool_header->column_header = strdup (column_header);
-  tool_header->full_header = buf_start;
-  return tool_header;
-}
-
-
-/* Parse FILENAME for branch mispredict lines into a structure
-   PMU_DATA. Returns 0 on on success.  Returns non-zero on
-   failure.  */
-
-static int
-parse_pfmon_branch_mispredicts (char *filename, void *pmu_data)
-{
-  FILE *fp;
-  size_t buflen = 2*1024;
-  char *buf;
-  brm_infos_t *brm_infos = (brm_infos_t *)pmu_data;
-  gcov_pmu_tool_header_t *tool_header = 0;
-
-  if ((fp = fopen (filename, "r")) == NULL)
-    {
-      fprintf (stderr, "cannot open pmu data file: %s\n", filename);
-      return 1;
-    }
-
-  if (!(tool_header = parse_pfmon_tool_header (fp, pfmon_bm_header)))
-    {
-      fprintf (stderr, "cannot parse pmu data file header: %s\n", filename);
-      return 1;
-    }
-
-  buf = XNEWVEC (char, buflen);
-  while (fgets (buf, buflen, fp))
-    {
-      gcov_pmu_brm_info_t *brm = XNEW (gcov_pmu_brm_info_t);
-      if (!parse_branch_mispredict_line (buf, brm))
-        {
-          /* Valid line, add to the array.  */
-          brm_infos->brm_count++;
-          if (brm_infos->brm_count >= brm_infos->alloc_brm_count)
-            {
-              /* Do we need to realloc? */
-              brm_infos->brm_array =
-                realloc (brm_infos->brm_array,
-                         2 * brm_infos->alloc_brm_count);
-              if (brm_infos->brm_array == NULL) {
-                fprintf (stderr,
-                         "Cannot allocate memory for br mispredicts.\n");
-                __destroy_pmu_tool_header (tool_header);
-                free (buf);
-                fclose (fp);
-                return 1;
-              }
-            }
-          brm_infos->brm_array[brm_infos->brm_count - 1] = brm;
-        }
-      else
-        /* Delete invalid line.  */
-        XDELETE (brm);
-    }
-  free (buf);
-  fclose (fp);
-  brm_infos->pmu_tool_header = tool_header;
-  return 0;
-}
-
-/* Start the monitoring process using pmu tool. Return 0 on success,
-   non-zero otherwise.  */
-
-static int
-pmu_start (void)
-{
-  pid_t pid;
-
-  /* no start function */
-  if (!the_pmu_tool_info->tool_details->start_pmu_module)
-    return 1;
-
-  pid = fork ();
-  if (pid == -1)
-    {
-      /* error condition */
-      fprintf (stderr, "Cannot create PMU profiling process, exiting.\n");
-      return 1;
-    }
-  else if (pid == 0)
-    {
-      /* child */
-      pid_t ppid = getppid();
-      char *tmpfile = the_pmu_tool_info->raw_pmu_profile_filename;
-      const char **pfmon_args = the_pmu_tool_info->tool_details->arg_array;
-      int new_stderr_fd;
-
-      /* Redirect stderr from the child process into a separate file.  */
-      new_stderr_fd = creat (the_pmu_tool_info->tool_stderr_filename,
-                             S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
-      if (new_stderr_fd != -1)
-          dup2 (new_stderr_fd, 2);
-      /* The following does an exec and thus is not expected to return.  */
-      the_pmu_tool_info->tool_details->start_pmu_module(ppid, tmpfile,
-                                                        pfmon_args);
-      /* exec returned, an error condition.  */
-      fprintf (stderr, "could not create profiling process: %s\n",
-               the_pmu_tool_info->tool_details->arg_array[0]);
-      _exit (0);
-    }
-  else
-    {
-      /* parent */
-      the_pmu_tool_info->pmu_tool_pid = pid;
-      return 0;
-    }
-}
-
 /* Allocate and initialize pmu load latency structure.  */
 
 static void *
@@ -1205,160 +154,6 @@  init_pmu_branch_mispredict (void)
   return (void *)brm_info;
 }
 
-/* Initialize pmu tool based upon PMU_INFO. Sets the appropriate tool
-   type in the global the_pmu_tool_info.  */
-
-static int
-init_pmu_tool (struct gcov_pmu_info *pmu_info)
-{
-  the_pmu_tool_info->pmu_profiling_state = PMU_NONE;
-  the_pmu_tool_info->verbose = 0;
-  the_pmu_tool_info->tool = PTT_PFMON;  /* we support only pfmon */
-  the_pmu_tool_info->pmu_tool_pid = 0;
-  the_pmu_tool_info->top_n_address = pmu_info->pmu_top_n_address;
-  the_pmu_tool_info->symbolizer_pid = 0;
-  the_pmu_tool_info->symbolizer_to_pipefd[0] = -1;
-  the_pmu_tool_info->symbolizer_to_pipefd[1] = -1;
-  the_pmu_tool_info->symbolizer_from_pipefd[0] = -1;
-  the_pmu_tool_info->symbolizer_from_pipefd[1] = -1;
-
-  if (parse_pmu_profile_options (pmu_info->pmu_tool))
-    return 1;
-
-  if (the_pmu_tool_info->pmu_profiling_state == PMU_ERROR)
-    {
-      fprintf (stderr, "Unsupported PMU module: %s, disabling PMU profiling.\n",
-               pmu_info->pmu_tool);
-      return 1;
-    }
-
-  if (the_pmu_tool_info->tool_details->init_pmu_module)
-    /* initialize module */
-    the_pmu_tool_info->pmu_data =
-      the_pmu_tool_info->tool_details->init_pmu_module();
-  return 0;
-}
-
-/* Initialize PMU profiling based upon the information passed in
-   PMU_INFO and use pmu_profile_filename as the file to store the PMU
-   profile.  This is called multiple times from libgcov, once per
-   object file.  We need to make sure to do the necessary
-   initialization only the first time.  For subsequent invocations it
-   behaves as a NOOP.  */
-
-void
-__gcov_init_pmu_profiler (struct gcov_pmu_info *pmu_info)
-{
-  char *raw_pmu_profile_filename;
-  char *tool_stderr_filename;
-  if (!pmu_info || !pmu_info->pmu_profile_filename || !pmu_info->pmu_tool)
-    return;
-
-  /* Allocate the global structure on first invocation.  */
-  if (!the_pmu_tool_info)
-    {
-      the_pmu_tool_info = XNEWVEC (struct pmu_tool_info, 1);
-      if (!the_pmu_tool_info)
-        {
-          fprintf (stderr, "Error allocating memory for PMU tool\n");
-          return;
-        }
-      if (init_pmu_tool (pmu_info))
-        {
-          /* Initialization error.  */
-          XDELETE (the_pmu_tool_info);
-          the_pmu_tool_info = 0;
-          return;
-        }
-    }
-
-  switch (the_pmu_tool_info->pmu_profiling_state)
-    {
-    case PMU_NONE:
-      the_pmu_tool_info->pmu_profile_filename =
-        strdup (pmu_info->pmu_profile_filename);
-      /* Construct an intermediate filename by substituting trailing
-         '.gcda' with '.pmud'.  */
-      raw_pmu_profile_filename = strdup (pmu_info->pmu_profile_filename);
-      if (raw_pmu_profile_filename == NULL)
-        {
-          fprintf (stderr, "Cannot allocate memory\n");
-          exit (1);
-        }
-      strcpy (raw_pmu_profile_filename + strlen (raw_pmu_profile_filename) - 4,
-              "pmud");
-
-      /* Construct a filename for collecting PMU tool's stderr by
-         substituting trailing '.gcda' with '.stderr'.  */
-      tool_stderr_filename =
-        XNEWVEC (char, strlen (pmu_info->pmu_profile_filename) + 1 + 2);
-      strcpy (tool_stderr_filename, pmu_info->pmu_profile_filename);
-      strcpy (tool_stderr_filename + strlen (tool_stderr_filename) - 4,
-              "stderr");
-      the_pmu_tool_info->raw_pmu_profile_filename = raw_pmu_profile_filename;
-      the_pmu_tool_info->tool_stderr_filename = tool_stderr_filename;
-      the_pmu_tool_info->pmu_profiling_state = PMU_INITIALIZED;
-      break;
-
-    case PMU_INITIALIZED:
-    case PMU_OFF:
-    case PMU_ON:
-    case PMU_ERROR:
-      break;
-    default:
-      break;
-    }
-}
-
-/* Start PMU profiling.  It updates the current state.  */
-
-void
-__gcov_start_pmu_profiler (void)
-{
-  if (!the_pmu_tool_info)
-    return;
-
-  switch (the_pmu_tool_info->pmu_profiling_state)
-    {
-    case PMU_INITIALIZED:
-      if (!pmu_start ())
-        the_pmu_tool_info->pmu_profiling_state = PMU_ON;
-      else
-        the_pmu_tool_info->pmu_profiling_state = PMU_ERROR;
-      break;
-
-    case PMU_NONE:
-      /* PMU was not properly initialized, don't attempt start it.  */
-      the_pmu_tool_info->pmu_profiling_state = PMU_ERROR;
-      break;
-
-    case PMU_OFF:
-      /* Restarting PMU is not yet supported.  */
-    case PMU_ON:
-      /* Do nothing.  */
-    case PMU_ERROR:
-      break;
-
-    default:
-      break;
-    }
-}
-
-/* Stop PMU profiling.  Currently it doesn't do anything except
-   bookkeeping.  */
-
-void
-__gcov_stop_pmu_profiler (void)
-{
-  if (!the_pmu_tool_info)
-    return;
-
-  if (the_pmu_tool_info->tool_details->stop_pmu_module)
-    the_pmu_tool_info->tool_details->stop_pmu_module();
-  if (the_pmu_tool_info->pmu_profiling_state == PMU_ON)
-    the_pmu_tool_info->pmu_profiling_state = PMU_OFF;
-}
-
 /* Write the load latency information LL_INFO into the gcda file.  */
 
 static void
@@ -1400,55 +195,6 @@  gcov_write_branch_mispredict_line (const gcov_pmu_
   gcov_write_string (brm_info->filename);
 }
 
-/* Write load latency information INFO into the gcda file.  The gcda
-   file has already been opened and is available for writing.  */
-
-static void
-gcov_write_load_latency_infos (void *info)
-{
-  unsigned i;
-  const ll_infos_t *ll_infos = (const ll_infos_t *)info;
-  gcov_unsigned_t stamp = 0;  /* Don't use stamp as we don't support merge.  */
-  /* We don't support merge, and instead always rewrite the file.  But
-     to rewrite a gcov file we must first read it, however the read
-     value is ignored.  */
-  gcov_read_unsigned ();
-  gcov_rewrite ();
-  gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
-  gcov_write_unsigned (stamp);
-  if (ll_infos->pmu_tool_header)
-    gcov_write_tool_header (ll_infos->pmu_tool_header);
-  for (i = 0; i < ll_infos->ll_count; ++i)
-    {
-      /* Write each line.  */
-      gcov_write_ll_line (ll_infos->ll_array[i]);
-    }
-  gcov_truncate ();
-}
-
-/* Write branch mispredict information INFO into the gcda file.  The
-   gcda file has already been opened and is available for writing.  */
-
-static void
-gcov_write_branch_mispredict_infos (void *info)
-{
-  unsigned i;
-  const brm_infos_t *brm_infos = (const brm_infos_t *)info;
-  gcov_unsigned_t stamp = 0;  /* Don't use stamp as we don't support merge. */
-  /* We don't support merge, and instead always rewrite the file.  */
-  gcov_rewrite ();
-  gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
-  gcov_write_unsigned (stamp);
-  if (brm_infos->pmu_tool_header)
-    gcov_write_tool_header (brm_infos->pmu_tool_header);
-  for (i = 0; i < brm_infos->brm_count; ++i)
-    {
-      /* Write each line.  */
-      gcov_write_branch_mispredict_line (brm_infos->brm_array[i]);
-    }
-  gcov_truncate ();
-}
-
 /* Compute TOOL_HEADER length for writing into the gcov file.  */
 
 static gcov_unsigned_t
@@ -1483,70 +229,4 @@  gcov_write_tool_header (gcov_pmu_tool_header_t *he
   gcov_write_string (header->full_header);
 }
 
-
-/* End PMU profiling. If GCDA_ERROR is non-zero then write profiling data into
-   already open gcda file */
-
-void
-__gcov_end_pmu_profiler (int gcda_error)
-{
-  int pid_status;
-  int wait_status;
-  pid_t pid;
-  pmu_tool_fns *tool_details;
-
-  if (!the_pmu_tool_info)
-    return;
-
-  tool_details = the_pmu_tool_info->tool_details;
-  pid = the_pmu_tool_info->pmu_tool_pid;
-  if (pid)
-    {
-      if (tool_debug)
-        fprintf (stderr, "terminating PMU profiling process %ld\n", (long)pid);
-      kill (pid, SIGTERM);
-      if (tool_debug)
-        fprintf (stderr, "parent: waiting for pmu process to end\n");
-      wait_status = waitpid (pid, &pid_status, 0);
-      if (tool_debug) {
-        if (wait_status == pid)
-          fprintf (stderr, "Normal exit. Child terminated.\n");
-        else
-          fprintf (stderr, "Abnormal exit. child status, %d.\n", pid_status);
-      }
-    }
-
-  if (the_pmu_tool_info->pmu_profiling_state != PMU_OFF)
-    {
-      /* nothing to do */
-      fprintf (stderr,
-               "__gcov_dump_pmu_profile: incorrect pmu state: %d, pid: %ld\n",
-               the_pmu_tool_info->pmu_profiling_state,
-               (unsigned long)pid);
-      return;
-    }
-
-  if (!tool_details->parse_pmu_output)
-    return;
-
-  /* Since we are going to parse the output, we also need symbolizer.  */
-  if (tool_details->start_symbolizer)
-    tool_details->start_symbolizer (getpid ());
-
-  if (!tool_details->parse_pmu_output
-      (the_pmu_tool_info->raw_pmu_profile_filename,
-       the_pmu_tool_info->pmu_data))
-    {
-      if (!gcda_error && tool_details->gcov_write_pmu_data)
-        /* Write tool output into the gcda file.  */
-        tool_details->gcov_write_pmu_data (the_pmu_tool_info->pmu_data);
-    }
-
-  if (tool_details->end_symbolizer)
-    tool_details->end_symbolizer ();
-
-  if (tool_details->cleanup_pmu_data)
-    tool_details->cleanup_pmu_data (the_pmu_tool_info->pmu_data);
-}
-
 #endif
Index: libgcc/libgcov.c
===================================================================
--- libgcc/libgcov.c	(revision 190135)
+++ libgcc/libgcov.c	(working copy)
@@ -463,37 +463,6 @@  gcov_alloc_filename (void)
   gi_filename_up = gi_filename + prefix_length;
 }
 
-/* Stop the pmu profiler and dump pmu profile info into the global file.  */
-
-static void
-pmu_profile_stop (void)
-{
-  const char *pmu_profile_filename =  __gcov_pmu_profile_filename;
-  const char *pmu_options = __gcov_pmu_profile_options;
-  size_t filename_length;
-  int gcda_error;
-
-  if (!pmu_profile_filename || !pmu_options)
-    return;
-
-  __gcov_stop_pmu_profiler ();
-
-  filename_length = strlen (pmu_profile_filename);
-  if (filename_length > gcov_max_filename)
-    gcov_max_filename = filename_length;
-  /* Allocate and initialize the filename scratch space.  */
-  gcov_alloc_filename ();
-  GCOV_GET_FILENAME (prefix_length, gcov_prefix_strip, pmu_profile_filename,
-                     gi_filename_up);
-  /* Open the gcda file for writing. We don't support merge yet.  */
-  gcda_error = gcov_open_by_filename (gi_filename);
-  __gcov_end_pmu_profiler (gcda_error);
-  if ((gcda_error = gcov_close ()))
-    gcov_error (gcda_error  < 0 ?  "pmu_profile_stop:%s:Overflow writing\n" :
-                "pmu_profile_stop:%s:Error writing\n",
-                gi_filename);
-}
-
 /* Sort N entries in VALUE_ARRAY in descending order.
    Each entry in VALUE_ARRAY has two values. The sorting
    is based on the second value.  */
@@ -634,9 +603,6 @@  gcov_exit (void)
   if (gcov_dump_complete)
     return;
 
-  /* Stop and write the PMU profile data into the global file.  */
-  pmu_profile_stop ();
-
   dump_module_info = gcov_exit_init ();
 
   for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
@@ -701,25 +667,11 @@  __gcov_init (struct gcov_info *info)
     {
       const char *ptr = info->filename;
       size_t filename_length = strlen (info->filename);
-      struct gcov_pmu_info pmu_info;
 
       /* Refresh the longest file name information.  */
       if (filename_length > gcov_max_filename)
         gcov_max_filename = filename_length;
 
-      /* Initialize the pmu profiler.  */
-      pmu_info.pmu_profile_filename = __gcov_pmu_profile_filename;
-      pmu_info.pmu_tool = __gcov_pmu_profile_options;
-      pmu_info.pmu_top_n_address = __gcov_pmu_top_n_address;
-      __gcov_init_pmu_profiler (&pmu_info);
-      if (pmu_info.pmu_profile_filename)
-        {
-          /* Refresh the longest file name information.  */
-          filename_length = strlen (pmu_info.pmu_profile_filename);
-          if (filename_length > gcov_max_filename)
-            gcov_max_filename = filename_length;
-        }
-
       /* Assign the module ID (starting at 1).  */
       info->mod_info->ident = (++gcov_cur_module_id);
       gcc_assert (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (GEN_FUNC_GLOBAL_ID (
@@ -729,8 +681,6 @@  __gcov_init (struct gcov_info *info)
       if (!__gcov_list)
         {
           atexit (gcov_exit);
-          /* Start pmu profiler. */
-          __gcov_start_pmu_profiler ();
         }
 
       info->next = __gcov_list;
@@ -746,10 +696,8 @@  __gcov_init (struct gcov_info *info)
 void
 __gcov_flush (void)
 {
-  __gcov_stop_pmu_profiler ();
   gcov_exit ();
   gcov_clear ();
-  __gcov_start_pmu_profiler ();
 }
 
 #else /* __GCOV_KERNEL__ */