/* Optimization statistics functions.
   Copyright (C) 2008-2021 Free Software Foundation, Inc.
   Contributed by Richard Guenther  <rguenther@suse.de>

This file is part of GCC.

GCC 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, or (at your option) any later
version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "function.h"
#include "tree-pass.h"
#include "context.h"
#include "pass_manager.h"

static int statistics_dump_nr;
static dump_flags_t statistics_dump_flags;
static FILE *statistics_dump_file;

/* Statistics entry.  A integer counter associated to a string ID
   and value.  */

struct statistics_counter {
  const char *id;
  int val;
  bool histogram_p;
  unsigned HOST_WIDE_INT count;
  unsigned HOST_WIDE_INT prev_dumped_count;
};

/* Hashtable helpers.  */

struct stats_counter_hasher : pointer_hash <statistics_counter>
{
  static inline hashval_t hash (const statistics_counter *);
  static inline bool equal (const statistics_counter *,
			    const statistics_counter *);
  static inline void remove (statistics_counter *);
};

/* Hash a statistic counter by its string ID.  */

inline hashval_t
stats_counter_hasher::hash (const statistics_counter *c)
{
  return htab_hash_string (c->id) + c->val;
}

/* Compare two statistic counters by their string IDs.  */

inline bool
stats_counter_hasher::equal (const statistics_counter *c1,
			     const statistics_counter *c2)
{
  return c1->val == c2->val && strcmp (c1->id, c2->id) == 0;
}

/* Free a statistics entry.  */

inline void
stats_counter_hasher::remove (statistics_counter *v)
{
  free (CONST_CAST (char *, v->id));
  free (v);
}

typedef hash_table<stats_counter_hasher> stats_counter_table_type;

/* Array of statistic hashes, indexed by pass id.  */
static stats_counter_table_type **statistics_hashes;
static unsigned nr_statistics_hashes;

/* Return the current hashtable to be used for recording or printing
   statistics.  */

static stats_counter_table_type *
curr_statistics_hash (void)
{
  unsigned idx;

  gcc_assert (current_pass->static_pass_number >= 0);
  idx = current_pass->static_pass_number;

  if (idx < nr_statistics_hashes
      && statistics_hashes[idx])
    return statistics_hashes[idx];

  if (idx >= nr_statistics_hashes)
    {
      statistics_hashes = XRESIZEVEC (stats_counter_table_type *,
				      statistics_hashes, idx+1);
      memset (statistics_hashes + nr_statistics_hashes, 0,
	      (idx + 1 - nr_statistics_hashes)
	      * sizeof (stats_counter_table_type *));
      nr_statistics_hashes = idx + 1;
    }

  statistics_hashes[idx] = new stats_counter_table_type (15);

  return statistics_hashes[idx];
}

/* Helper for statistics_fini_pass.  Print the counter difference
   since the last dump for the pass dump files.  */

int
statistics_fini_pass_1 (statistics_counter **slot,
			void *data ATTRIBUTE_UNUSED)
{
  statistics_counter *counter = *slot;
  unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
  if (count == 0)
    return 1;
  if (counter->histogram_p)
    fprintf (dump_file, "%s == %d: " HOST_WIDE_INT_PRINT_DEC "\n",
	     counter->id, counter->val, count);
  else
    fprintf (dump_file, "%s: " HOST_WIDE_INT_PRINT_DEC "\n",
	     counter->id, count);
  counter->prev_dumped_count = counter->count;
  return 1;
}

/* Helper for statistics_fini_pass.  Print the counter difference
   since the last dump for the statistics dump.  */

int
statistics_fini_pass_2 (statistics_counter **slot,
			void *data ATTRIBUTE_UNUSED)
{
  statistics_counter *counter = *slot;
  unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
  if (count == 0)
    return 1;
  counter->prev_dumped_count = counter->count;
  if (counter->histogram_p)
    fprintf (statistics_dump_file,
	     "%d %s \"%s == %d\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
	     current_pass->static_pass_number,
	     current_pass->name,
	     counter->id, counter->val,
	     current_function_name (),
	     count);
  else
    fprintf (statistics_dump_file,
	     "%d %s \"%s\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
	     current_pass->static_pass_number,
	     current_pass->name,
	     counter->id,
	     current_function_name (),
	     count);
  counter->prev_dumped_count = counter->count;
  return 1;
}

/* Helper for statistics_fini_pass, reset the counters.  */

int
statistics_fini_pass_3 (statistics_counter **slot,
			void *data ATTRIBUTE_UNUSED)
{
  statistics_counter *counter = *slot;
  counter->prev_dumped_count = counter->count;
  return 1;
}

/* Dump the current statistics incrementally.  */

void
statistics_fini_pass (void)
{
  if (current_pass->static_pass_number == -1)
    return;

  if (dump_file
      && dump_flags & TDF_STATS)
    {
      fprintf (dump_file, "\n");
      fprintf (dump_file, "Pass statistics of \"%s\": ", current_pass->name);
      fprintf (dump_file, "----------------\n");
      curr_statistics_hash ()
	->traverse_noresize <void *, statistics_fini_pass_1> (NULL);
      fprintf (dump_file, "\n");
    }
  if (statistics_dump_file
      && !(statistics_dump_flags & TDF_STATS
	   || statistics_dump_flags & TDF_DETAILS))
    curr_statistics_hash ()
      ->traverse_noresize <void *, statistics_fini_pass_2> (NULL);
  curr_statistics_hash ()
    ->traverse_noresize <void *, statistics_fini_pass_3> (NULL);
}

/* Helper for printing summary information.  */

int
statistics_fini_1 (statistics_counter **slot, opt_pass *pass)
{
  statistics_counter *counter = *slot;
  if (counter->count == 0)
    return 1;
  if (counter->histogram_p)
    fprintf (statistics_dump_file,
	     "%d %s \"%s == %d\" " HOST_WIDE_INT_PRINT_DEC "\n",
	     pass->static_pass_number,
	     pass->name,
	     counter->id, counter->val,
	     counter->count);
  else
    fprintf (statistics_dump_file,
	     "%d %s \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
	     pass->static_pass_number,
	     pass->name,
	     counter->id,
	     counter->count);
  return 1;
}

/* Finish the statistics and dump summary information.  */

void
statistics_fini (void)
{
  gcc::pass_manager *passes = g->get_passes ();
  if (!statistics_dump_file)
    return;

  if (statistics_dump_flags & TDF_STATS)
    {
      unsigned i;
      for (i = 0; i < nr_statistics_hashes; ++i)
	if (statistics_hashes[i]
	    && passes->get_pass_for_id (i) != NULL)
	  statistics_hashes[i]
	    ->traverse_noresize <opt_pass *, statistics_fini_1>
	    (passes->get_pass_for_id (i));
    }

  dump_end (statistics_dump_nr, statistics_dump_file);
}

/* Register the statistics dump file.  */

void
statistics_early_init (void)
{
  gcc::dump_manager *dumps = g->get_dumps ();
  statistics_dump_nr = dumps->dump_register (".statistics", "statistics",
					     "statistics", DK_tree,
					     OPTGROUP_NONE,
					     false);
}

/* Init the statistics.  */

void
statistics_init (void)
{
  gcc::dump_manager *dumps = g->get_dumps ();
  statistics_dump_file = dump_begin (statistics_dump_nr, NULL);
  statistics_dump_flags = dumps->get_dump_file_info (statistics_dump_nr)->pflags;
}

/* Lookup or add a statistics counter in the hashtable HASH with ID, VAL
   and HISTOGRAM_P.  */

static statistics_counter *
lookup_or_add_counter (stats_counter_table_type *hash, const char *id, int val,
		       bool histogram_p)
{
  statistics_counter **counter;
  statistics_counter c;
  c.id = id;
  c.val = val;
  counter = hash->find_slot (&c, INSERT);
  if (!*counter)
    {
      *counter = XNEW (statistics_counter);
      (*counter)->id = xstrdup (id);
      (*counter)->val = val;
      (*counter)->histogram_p = histogram_p;
      (*counter)->prev_dumped_count = 0;
      (*counter)->count = 0;
    }
  return *counter;
}

/* Add statistics information about event ID in function FN.
   This will increment the counter associated with ID by INCR.
   It will also dump the event to the global statistics file if requested.  */

void
statistics_counter_event (struct function *fn, const char *id, int incr)
{
  statistics_counter *counter;

  if ((!(dump_flags & TDF_STATS)
       && !statistics_dump_file)
      || incr == 0)
    return;

  if (current_pass
      && current_pass->static_pass_number != -1)
    {
      counter = lookup_or_add_counter (curr_statistics_hash (), id, 0, false);
      gcc_assert (!counter->histogram_p);
      counter->count += incr;
    }

  if (!statistics_dump_file
      || !(statistics_dump_flags & TDF_DETAILS))
    return;

  fprintf (statistics_dump_file,
	   "%d %s \"%s\" \"%s\" %d\n",
	   current_pass ? current_pass->static_pass_number : -1,
	   current_pass ? current_pass->name : "none",
	   id,
	   function_name (fn),
	   incr);
}

/* Add statistics information about event ID in function FN with the
   histogram value VAL.
   It will dump the event to the global statistics file if requested.  */

void
statistics_histogram_event (struct function *fn, const char *id, int val)
{
  statistics_counter *counter;

  if (!(dump_flags & TDF_STATS)
      && !statistics_dump_file)
    return;

  counter = lookup_or_add_counter (curr_statistics_hash (), id, val, true);
  gcc_assert (counter->histogram_p);
  counter->count += 1;

  if (!statistics_dump_file
      || !(statistics_dump_flags & TDF_DETAILS))
    return;

  fprintf (statistics_dump_file,
	   "%d %s \"%s == %d\" \"%s\" 1\n",
	   current_pass->static_pass_number,
	   current_pass->name,
	   id, val,
	   function_name (fn));
}
