This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [google] Remove deprecated pfmon-specific functions/structs from pmu-profile.c (issue6442086)
- From: Teresa Johnson <tejohnson at google dot com>
- To: Chris Manghane <cmang at google dot com>
- Cc: reply at codereview dot appspotmail dot com, singhai at google dot com, gcc-patches at gcc dot gnu dot org
- Date: Wed, 8 Aug 2012 19:47:20 -0700
- Subject: Re: [google] Remove deprecated pfmon-specific functions/structs from pmu-profile.c (issue6442086)
- References: <20120807225534.AA4DF140ADD@rainbowponydeluxe.mtv.corp.google.com>
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, <_10, <_32, <_64, <_256,
> - <_1024, >_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
--
Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413