/* basic_blocks.c  -  Basic-block level related code: reading/writing
   of basic-block info to/from gmon.out; computing and formatting of
   basic-block related statistics.

   Copyright (C) 1999-2016 Free Software Foundation, Inc.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */

#include "gprof.h"
#include "libiberty.h"
#include "filenames.h"
#include "basic_blocks.h"
#include "corefile.h"
#include "gmon_io.h"
#include "gmon_out.h"
#include "search_list.h"
#include "source.h"
#include "symtab.h"
#include "sym_ids.h"

static int cmp_bb (const PTR, const PTR);
static int cmp_ncalls (const PTR, const PTR);
static void fskip_string (FILE *);
static void annotate_with_count (char *, unsigned int, int, PTR);

/* Default option values:  */
bfd_boolean bb_annotate_all_lines = FALSE;
unsigned long bb_min_calls = 1;
int bb_table_length = 10;

/* Variables used to compute annotated source listing stats:  */
static long num_executable_lines;
static long num_lines_executed;


/* Helper for sorting.  Compares two symbols and returns result
   such that sorting will be increasing according to filename, line
   number, and address (in that order).  */

static int
cmp_bb (const PTR lp, const PTR rp)
{
  int r;
  const Sym *left = *(const Sym **) lp;
  const Sym *right = *(const Sym **) rp;

  if (left->file && right->file)
    {
      r = filename_cmp (left->file->name, right->file->name);

      if (r)
	return r;

      if (left->line_num != right->line_num)
	return left->line_num - right->line_num;
    }

  if (left->addr < right->addr)
    return -1;
  else if (left->addr > right->addr)
    return 1;
  else
    return 0;
}


/* Helper for sorting.  Order basic blocks in decreasing number of
   calls, ties are broken in increasing order of line numbers.  */
static int
cmp_ncalls (const PTR lp, const PTR rp)
{
  const Sym *left = *(const Sym **) lp;
  const Sym *right = *(const Sym **) rp;

  if (!left)
    return 1;
  else if (!right)
    return -1;

  if (left->ncalls < right->ncalls)
    return 1;
  else if (left->ncalls > right->ncalls)
    return -1;

  return left->line_num - right->line_num;
}

/* Skip over variable length string.  */
static void
fskip_string (FILE *fp)
{
  int ch;

  while ((ch = fgetc (fp)) != EOF)
    {
      if (ch == '\0')
	break;
    }
}

/* Read a basic-block record from file IFP.  FILENAME is the name
   of file IFP and is provided for formatting error-messages only.  */

void
bb_read_rec (FILE *ifp, const char *filename)
{
  unsigned int nblocks, b;
  bfd_vma addr, ncalls;
  Sym *sym;

  if (gmon_io_read_32 (ifp, &nblocks))
    {
      fprintf (stderr, _("%s: %s: unexpected end of file\n"),
	       whoami, filename);
      done (1);
    }

  nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks);
  if (gmon_file_version == 0)
    fskip_string (ifp);

  for (b = 0; b < nblocks; ++b)
    {
      if (gmon_file_version == 0)
	{
	  int line_num;

	  /* Version 0 had lots of extra stuff that we don't
	     care about anymore.  */
	  if ((fread (&ncalls, sizeof (ncalls), 1, ifp) != 1)
	      || (fread (&addr, sizeof (addr), 1, ifp) != 1)
	      || (fskip_string (ifp), FALSE)
	      || (fskip_string (ifp), FALSE)
	      || (fread (&line_num, sizeof (line_num), 1, ifp) != 1))
	    {
	      perror (filename);
	      done (1);
	    }
	}
      else if (gmon_io_read_vma (ifp, &addr)
	       || gmon_io_read_vma (ifp, &ncalls))
	{
	  perror (filename);
	  done (1);
	}

      /* Basic-block execution counts are meaningful only if we're
	 profiling at the line-by-line level:  */
      if (line_granularity)
	{
	  sym = sym_lookup (&symtab, addr);

	  if (sym)
	    {
	      int i;

	      DBG (BBDEBUG,
		   printf ("[bb_read_rec] 0x%lx->0x%lx (%s:%d) cnt=%lu\n",
			   (unsigned long) addr, (unsigned long) sym->addr,
			   sym->name, sym->line_num, (unsigned long) ncalls));

	      for (i = 0; i < NBBS; i++)
		{
		  if (! sym->bb_addr[i] || sym->bb_addr[i] == addr)
		    {
		      sym->bb_addr[i] = addr;
		      sym->bb_calls[i] += ncalls;
		      break;
		    }
		}
	    }
	}
      else
	{
	  static bfd_boolean user_warned = FALSE;

	  if (!user_warned)
	    {
	      user_warned = TRUE;
	      fprintf (stderr,
  _("%s: warning: ignoring basic-block exec counts (use -l or --line)\n"),
		       whoami);
	    }
	}
    }
  return;
}

/* Write all basic-blocks with non-zero counts to file OFP.  FILENAME
   is the name of OFP and is provided for producing error-messages
   only.  */
void
bb_write_blocks (FILE *ofp, const char *filename)
{
  unsigned int nblocks = 0;
  Sym *sym;
  int i;

  /* Count how many non-zero blocks with have:  */
  for (sym = symtab.base; sym < symtab.limit; ++sym)
    {
      for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
	;
      nblocks += i;
    }

  /* Write header:  */
  if (gmon_io_write_8 (ofp, GMON_TAG_BB_COUNT)
      || gmon_io_write_32 (ofp, nblocks))
    {
      perror (filename);
      done (1);
    }

  /* Write counts:  */
  for (sym = symtab.base; sym < symtab.limit; ++sym)
    {
      for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
	{
	  if (gmon_io_write_vma (ofp, sym->bb_addr[i])
	      || gmon_io_write_vma (ofp, (bfd_vma) sym->bb_calls[i]))
	    {
	      perror (filename);
	      done (1);
	    }
	}
    }
}

/* Output basic-block statistics in a format that is easily parseable.
   Current the format is:

	<filename>:<line-number>: (<function-name>:<bb-addr): <ncalls>  */

void
print_exec_counts (void)
{
  Sym **sorted_bbs, *sym;
  unsigned int i, j, len;

  if (first_output)
    first_output = FALSE;
  else
    printf ("\f\n");

  /* Sort basic-blocks according to function name and line number:  */
  sorted_bbs = (Sym **) xmalloc (symtab.len * sizeof (sorted_bbs[0]));
  len = 0;

  for (sym = symtab.base; sym < symtab.limit; ++sym)
    {
      /* Accept symbol if it's in the INCL_EXEC table
	 or there is no INCL_EXEC table
	 and it does not appear in the EXCL_EXEC table.  */
      if (sym_lookup (&syms[INCL_EXEC], sym->addr)
	  || (syms[INCL_EXEC].len == 0
	      && !sym_lookup (&syms[EXCL_EXEC], sym->addr)))
	{
	  sorted_bbs[len++] = sym;
	}
    }

  qsort (sorted_bbs, len, sizeof (sorted_bbs[0]), cmp_bb);

  /* Output basic-blocks:  */

  for (i = 0; i < len; ++i)
    {
      sym = sorted_bbs [i];

      if (sym->ncalls > 0 || ! ignore_zeros)
	{
	  /* FIXME: This only works if bfd_vma is unsigned long.  */
	  printf (_("%s:%d: (%s:0x%lx) %lu executions\n"),
		  sym->file ? sym->file->name : _("<unknown>"), sym->line_num,
		  sym->name, (unsigned long) sym->addr, sym->ncalls);
	}

      for (j = 0; j < NBBS && sym->bb_addr[j]; j ++)
	{
	  if (sym->bb_calls[j] > 0 || ! ignore_zeros)
	    {
	      /* FIXME: This only works if bfd_vma is unsigned long.  */
	      printf (_("%s:%d: (%s:0x%lx) %lu executions\n"),
		      sym->file ? sym->file->name : _("<unknown>"), sym->line_num,
		      sym->name, (unsigned long) sym->bb_addr[j],
		      sym->bb_calls[j]);
	    }
	}
    }
  free (sorted_bbs);
}

/* Helper for bb_annotated_source: format annotation containing
   number of line executions.  Depends on being called on each
   line of a file in sequential order.

   Global variable bb_annotate_all_lines enables execution count
   compression (counts are supressed if identical to the last one)
   and prints counts on all executed lines.  Otherwise, print
   all basic-block execution counts exactly once on the line
   that starts the basic-block.  */

static void
annotate_with_count (char *buf, unsigned int width, int line_num, PTR arg)
{
  Source_File *sf = (Source_File *) arg;
  Sym *b;
  unsigned int i;
  static unsigned long last_count;
  unsigned long last_print = (unsigned long) -1;

  b = NULL;

  if (line_num <= sf->num_lines)
    b = (Sym *) sf->line[line_num - 1];

  if (!b)
    {
      for (i = 0; i < width; i++)
	buf[i] = ' ';
      buf[width] = '\0';
    }
  else
    {
      char tmpbuf[NBBS * 30];
      char *p;
      unsigned long ncalls;
      int ncalls_set;
      unsigned int len;

      ++num_executable_lines;

      p = tmpbuf;
      *p = '\0';

      ncalls = 0;
      ncalls_set = 0;

      /* If this is a function entry point, label the line no matter what.
	 Otherwise, we're in the middle of a function, so check to see
	 if the first basic-block address is larger than the starting
	 address of the line.  If so, then this line begins with a
	 a portion of the previous basic-block, so print that prior
	 execution count (if bb_annotate_all_lines is set).  */
      if (b->is_func)
	{
	  sprintf (p, "%lu", b->ncalls);
	  p += strlen (p);
	  last_count = b->ncalls;
	  last_print = last_count;
	  ncalls = b->ncalls;
	  ncalls_set = 1;
	}
      else if (bb_annotate_all_lines
	       && b->bb_addr[0] && b->bb_addr[0] > b->addr)
	{
	  sprintf (p, "%lu", last_count);
	  p += strlen (p);
	  last_print = last_count;
	  ncalls = last_count;
	  ncalls_set = 1;
	}

      /* Loop through all of this line's basic-blocks.  For each one,
	 update last_count, then compress sequential identical counts
	 (if bb_annotate_all_lines) and print the execution count.  */

      for (i = 0; i < NBBS && b->bb_addr[i]; i++)
	{
	  last_count = b->bb_calls[i];
	  if (! ncalls_set)
	    {
	      ncalls = 0;
	      ncalls_set = 1;
	    }
	  ncalls += last_count;

	  if (bb_annotate_all_lines && last_count == last_print)
	    continue;

	  if (p > tmpbuf)
	    *p++ = ',';
	  sprintf (p, "%lu", last_count);
	  p += strlen (p);

	  last_print = last_count;
	}

      /* We're done.  If nothing has been printed on this line,
	 print the last execution count (bb_annotate_all_lines),
	 which could be from either a previous line (if there were
	 no BBs on this line), or from this line (if all our BB
	 counts were compressed out because they were identical).  */

      if (bb_annotate_all_lines && p == tmpbuf)
	{
	  sprintf (p, "%lu", last_count);
	  p += strlen (p);
	  ncalls = last_count;
	  ncalls_set = 1;
	}

      if (! ncalls_set)
	{
	  unsigned int c;

	  for (c = 0; c < width; c++)
	    buf[c] = ' ';
	  buf[width] = '\0';
	  return;
	}

      ++num_lines_executed;

      if (ncalls < bb_min_calls)
	{
	  strcpy (tmpbuf, "#####");
	  p = tmpbuf + 5;
	}

      strcpy (p, " -> ");
      p += 4;

      len = p - tmpbuf;
      if (len >= width)
	{
	  strncpy (buf, tmpbuf, width);
	  buf[width] = '\0';
	}
      else
	{
	  unsigned int c;

	  strcpy (buf + width - len, tmpbuf);
	  for (c = 0; c < width - len; ++c)
	    buf[c] = ' ';
	}
    }
}

/* Annotate the files named in SOURCE_FILES with basic-block statistics
   (execution counts).  After each source files, a few statistics
   regarding that source file are printed.  */

void
print_annotated_source (void)
{
  Sym *sym, *line_stats, *new_line;
  Source_File *sf;
  int i, table_len;
  FILE *ofp;

  /* Find maximum line number for each source file that user is
     interested in:  */
  for (sym = symtab.base; sym < symtab.limit; ++sym)
    {
      /* Accept symbol if it's file is known, its line number is
	 bigger than anything we have seen for that file so far and
	 if it's in the INCL_ANNO table or there is no INCL_ANNO
	 table and it does not appear in the EXCL_ANNO table.  */
      if (sym->file && sym->line_num > sym->file->num_lines
	  && (sym_lookup (&syms[INCL_ANNO], sym->addr)
	      || (syms[INCL_ANNO].len == 0
		  && !sym_lookup (&syms[EXCL_ANNO], sym->addr))))
	{
	  sym->file->num_lines = sym->line_num;
	}
    }

  /* Allocate line descriptors:  */
  for (sf = first_src_file; sf; sf = sf->next)
    {
      if (sf->num_lines > 0)
	{
	  sf->line = (void **) xmalloc (sf->num_lines * sizeof (sf->line[0]));
	  memset (sf->line, 0, sf->num_lines * sizeof (sf->line[0]));
	}
    }

  /* Count executions per line:  */
  for (sym = symtab.base; sym < symtab.limit; ++sym)
    {
      if (sym->file && sym->file->num_lines
	  && (sym_lookup (&syms[INCL_ANNO], sym->addr)
	      || (syms[INCL_ANNO].len == 0
		  && !sym_lookup (&syms[EXCL_ANNO], sym->addr))))
	{
	  sym->file->ncalls += sym->ncalls;
	  line_stats = (Sym *) sym->file->line[sym->line_num - 1];

	  if (!line_stats)
	    {
	      /* Common case has at most one basic-block per source line:  */
	      sym->file->line[sym->line_num - 1] = sym;
	    }
	  else if (!line_stats->addr)
	    {
	      /* sym is the 3rd .. nth basic block for this line:  */
	      line_stats->ncalls += sym->ncalls;
	    }
	  else
	    {
	      /* sym is the second basic block for this line.  */
	      new_line = (Sym *) xmalloc (sizeof (*new_line));
	      *new_line = *line_stats;
	      new_line->addr = 0;
	      new_line->ncalls += sym->ncalls;
	      sym->file->line[sym->line_num - 1] = new_line;
	    }
	}
    }

  /* Plod over source files, annotating them:  */
  for (sf = first_src_file; sf; sf = sf->next)
    {
      if (!sf->num_lines || (ignore_zeros && sf->ncalls == 0))
	continue;

      num_executable_lines = num_lines_executed = 0;

      ofp = annotate_source (sf, 16, annotate_with_count, sf);
      if (!ofp)
	continue;

      if (bb_table_length > 0)
	{
	  fprintf (ofp, _("\n\nTop %d Lines:\n\n     Line      Count\n\n"),
		   bb_table_length);

	  /* Abuse line arrays---it's not needed anymore:  */
	  qsort (sf->line, sf->num_lines, sizeof (sf->line[0]), cmp_ncalls);
	  table_len = bb_table_length;

	  if (table_len > sf->num_lines)
	    table_len = sf->num_lines;

	  for (i = 0; i < table_len; ++i)
	    {
	      sym = (Sym *) sf->line[i];

	      if (!sym || sym->ncalls == 0)
		  break;

	      fprintf (ofp, "%9d %10lu\n", sym->line_num, sym->ncalls);
	    }
	}

      free (sf->line);
      sf->line = 0;

      fprintf (ofp, _("\nExecution Summary:\n\n"));
      fprintf (ofp, _("%9ld   Executable lines in this file\n"),
	       num_executable_lines);
      fprintf (ofp, _("%9ld   Lines executed\n"), num_lines_executed);
      fprintf (ofp, _("%9.2f   Percent of the file executed\n"),
	       num_executable_lines
	       ? 100.0 * num_lines_executed / (double) num_executable_lines
	       : 100.0);
      fprintf (ofp, _("\n%9lu   Total number of line executions\n"),
	       sf->ncalls);
      fprintf (ofp, _("%9.2f   Average executions per line\n"),
	       num_executable_lines
	       ? (double) sf->ncalls / (double) num_executable_lines
	       : 0.0);

      if (ofp != stdout)
	fclose (ofp);
    }
}
