/* Profile counter container type.
   Copyright (C) 2017-2021 Free Software Foundation, Inc.
   Contributed by Jan Hubicka

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 "profile-count.h"
#include "options.h"
#include "tree.h"
#include "basic-block.h"
#include "function.h"
#include "cfg.h"
#include "gimple.h"
#include "data-streamer.h"
#include "cgraph.h"
#include "wide-int.h"
#include "sreal.h"

/* Names from profile_quality enum values.  */

const char *profile_quality_names[] =
{
  "uninitialized",
  "guessed_local",
  "guessed_global0",
  "guessed_global0adjusted",
  "guessed",
  "afdo",
  "adjusted",
  "precise"
};

/* Get a string describing QUALITY.  */

const char *
profile_quality_as_string (enum profile_quality quality)
{
  return profile_quality_names[quality];
}

/* Parse VALUE as profile quality and return true when a valid QUALITY.  */

bool
parse_profile_quality (const char *value, profile_quality *quality)
{
  for (unsigned i = 0; i < ARRAY_SIZE (profile_quality_names); i++)
    if (strcmp (profile_quality_names[i], value) == 0)
      {
	*quality = (profile_quality)i;
	return true;
      }

  return false;
}

/* Display names from profile_quality enum values.  */

const char *profile_quality_display_names[] =
{
  NULL,
  "estimated locally",
  "estimated locally, globally 0",
  "estimated locally, globally 0 adjusted",
  "guessed",
  "auto FDO",
  "adjusted",
  "precise"
};

/* Dump THIS to F.  */

void
profile_count::dump (FILE *f) const
{
  if (!initialized_p ())
    fprintf (f, "uninitialized");
  else
    fprintf (f, "%" PRId64 " (%s)", m_val,
	     profile_quality_display_names[m_quality]);
}

/* Dump THIS to stderr.  */

void
profile_count::debug () const
{
  dump (stderr);
  fprintf (stderr, "\n");
}

/* Return true if THIS differs from OTHER; tolerate small differences.  */

bool
profile_count::differs_from_p (profile_count other) const
{
  gcc_checking_assert (compatible_p (other));
  if (!initialized_p () || !other.initialized_p ())
    return false;
  if ((uint64_t)m_val - (uint64_t)other.m_val < 100
      || (uint64_t)other.m_val - (uint64_t)m_val < 100)
    return false;
  if (!other.m_val)
    return true;
  int64_t ratio = (int64_t)m_val * 100 / other.m_val;
  return ratio < 99 || ratio > 101;
}

/* Stream THIS from IB.  */

profile_count
profile_count::stream_in (class lto_input_block *ib)
{
  profile_count ret;
  ret.m_val = streamer_read_gcov_count (ib);
  ret.m_quality = (profile_quality) streamer_read_uhwi (ib);
  return ret;
}

/* Stream THIS to OB.  */

void
profile_count::stream_out (struct output_block *ob)
{
  streamer_write_gcov_count (ob, m_val);
  streamer_write_uhwi (ob, m_quality);
}

/* Stream THIS to OB.  */

void
profile_count::stream_out (struct lto_output_stream *ob)
{
  streamer_write_gcov_count_stream (ob, m_val);
  streamer_write_uhwi_stream (ob, m_quality);
}

/* Dump THIS to F.  */

void
profile_probability::dump (FILE *f) const
{
  if (!initialized_p ())
    fprintf (f, "uninitialized");
  else
    {
      /* Make difference between 0.00 as a roundoff error and actual 0.
	 Similarly for 1.  */
      if (m_val == 0)
        fprintf (f, "never");
      else if (m_val == max_probability)
        fprintf (f, "always");
      else
        fprintf (f, "%3.1f%%", (double)m_val * 100 / max_probability);
      if (m_quality == ADJUSTED)
	fprintf (f, " (adjusted)");
      else if (m_quality == AFDO)
	fprintf (f, " (auto FDO)");
      else if (m_quality == GUESSED)
	fprintf (f, " (guessed)");
    }
}

/* Dump THIS to stderr.  */

void
profile_probability::debug () const
{
  dump (stderr);
  fprintf (stderr, "\n");
}

/* Return true if THIS differs from OTHER; tolerate small differences.  */

bool
profile_probability::differs_from_p (profile_probability other) const
{
  if (!initialized_p () || !other.initialized_p ())
    return false;
  if ((uint64_t)m_val - (uint64_t)other.m_val < max_probability / 1000
      || (uint64_t)other.m_val - (uint64_t)max_probability < 1000)
    return false;
  if (!other.m_val)
    return true;
  int64_t ratio = (int64_t)m_val * 100 / other.m_val;
  return ratio < 99 || ratio > 101;
}

/* Return true if THIS differs significantly from OTHER.  */

bool
profile_probability::differs_lot_from_p (profile_probability other) const
{
  if (!initialized_p () || !other.initialized_p ())
    return false;
  uint32_t d = m_val > other.m_val ? m_val - other.m_val : other.m_val - m_val;
  return d > max_probability / 2;
}

/* Stream THIS from IB.  */

profile_probability
profile_probability::stream_in (class lto_input_block *ib)
{
  profile_probability ret;
  ret.m_val = streamer_read_uhwi (ib);
  ret.m_quality = (profile_quality) streamer_read_uhwi (ib);
  return ret;
}

/* Stream THIS to OB.  */

void
profile_probability::stream_out (struct output_block *ob)
{
  streamer_write_uhwi (ob, m_val);
  streamer_write_uhwi (ob, m_quality);
}

/* Stream THIS to OB.  */

void
profile_probability::stream_out (struct lto_output_stream *ob)
{
  streamer_write_uhwi_stream (ob, m_val);
  streamer_write_uhwi_stream (ob, m_quality);
}

/* Compute RES=(a*b + c/2)/c capping and return false if overflow happened.  */

bool
slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
{
  FIXED_WIDE_INT (128) tmp = a;
  wi::overflow_type overflow;
  tmp = wi::udiv_floor (wi::umul (tmp, b, &overflow) + (c / 2), c);
  gcc_checking_assert (!overflow);
  if (wi::fits_uhwi_p (tmp))
    {
      *res = tmp.to_uhwi ();
      return true;
    }
  *res = (uint64_t) -1;
  return false;
}

/* Return count as frequency within FUN scaled in range 0 to REG_FREQ_MAX
   Used for legacy code and should not be used anymore.  */

int
profile_count::to_frequency (struct function *fun) const
{
  if (!initialized_p ())
    return BB_FREQ_MAX;
  if (*this == zero ())
    return 0;
  STATIC_ASSERT (REG_BR_PROB_BASE == BB_FREQ_MAX);
  gcc_assert (fun->cfg->count_max.initialized_p ());
  profile_probability prob = probability_in (fun->cfg->count_max);
  if (!prob.initialized_p ())
    return REG_BR_PROB_BASE;
  return prob.to_reg_br_prob_base ();
}

/* Return count as frequency within FUN scaled in range 0 to CGRAPH_FREQ_MAX
   where CGRAPH_FREQ_BASE means that count equals to entry block count.
   Used for legacy code and should not be used anymore.  */

int
profile_count::to_cgraph_frequency (profile_count entry_bb_count) const
{
  if (!initialized_p () || !entry_bb_count.initialized_p ())
    return CGRAPH_FREQ_BASE;
  if (*this == zero ())
    return 0;
  gcc_checking_assert (entry_bb_count.initialized_p ());
  uint64_t scale;
  gcc_checking_assert (compatible_p (entry_bb_count));
  if (!safe_scale_64bit (!entry_bb_count.m_val ? m_val + 1 : m_val,
			 CGRAPH_FREQ_BASE, MAX (1, entry_bb_count.m_val), &scale))
    return CGRAPH_FREQ_MAX;
  return MIN (scale, CGRAPH_FREQ_MAX);
}

/* Return THIS/IN as sreal value.  */

sreal
profile_count::to_sreal_scale (profile_count in, bool *known) const
{
  if (!initialized_p () || !in.initialized_p ())
    {
      if (known)
	*known = false;
      return 1;
    }
  if (known)
    *known = true;
  /* Watch for cases where one count is IPA and other is not.  */
  if (in.ipa ().initialized_p ())
    {
      gcc_checking_assert (ipa ().initialized_p ());
      /* If current count is inter-procedurally 0 and IN is inter-procedurally
	 non-zero, return 0.  */
      if (in.ipa ().nonzero_p ()
	  && !ipa().nonzero_p ())
	return 0;
    }
  else 
    /* We can handle correctly 0 IPA count within locally estimated
       profile, but otherwise we are lost and this should not happen.   */
    gcc_checking_assert (!ipa ().initialized_p () || !ipa ().nonzero_p ());
  if (*this == zero ())
    return 0;
  if (m_val == in.m_val)
    return 1;
  gcc_checking_assert (compatible_p (in));

  if (!in.m_val)
    {
      if (!m_val)
	return 1;
      return m_val * 4;
    }
  return (sreal)m_val / (sreal)in.m_val;
}

/* We want to scale profile across function boundary from NUM to DEN.
   Take care of the side case when DEN is zeros.  We still want to behave
   sanely here which means
     - scale to profile_count::zero () if NUM is profile_count::zero
     - do not affect anything if NUM == DEN
     - preserve counter value but adjust quality in other cases.  */

void
profile_count::adjust_for_ipa_scaling (profile_count *num,
				       profile_count *den)
{
  /* Scaling is no-op if NUM and DEN are the same.  */
  if (*num == *den)
    return;
  /* Scaling to zero is always zero.  */
  if (*num == zero ())
    return;
  /* If den is non-zero we are safe.  */
  if (den->force_nonzero () == *den)
    return;
  /* Force both to non-zero so we do not push profiles to 0 when
     both num == 0 and den == 0.  */
  *den = den->force_nonzero ();
  *num = num->force_nonzero ();
}

/* THIS is a count of bb which is known to be executed IPA times.
   Combine this information into bb counter.  This means returning IPA
   if it is nonzero, not changing anything if IPA is uninitialized
   and if IPA is zero, turning THIS into corresponding local profile with
   global0.  */

profile_count
profile_count::combine_with_ipa_count (profile_count ipa)
{
  if (!initialized_p ())
    return *this;
  ipa = ipa.ipa ();
  if (ipa.nonzero_p ())
    return ipa;
  if (!ipa.initialized_p () || *this == zero ())
    return *this;
  if (ipa == zero ())
    return this->global0 ();
  return this->global0adjusted ();
}

/* Sae as profile_count::combine_with_ipa_count but within function with count
   IPA2.  */
profile_count
profile_count::combine_with_ipa_count_within (profile_count ipa,
					      profile_count ipa2)
{
  profile_count ret;
  if (!initialized_p ())
    return *this;
  if (ipa2.ipa () == ipa2 && ipa.initialized_p ())
    ret = ipa;
  else
    ret = combine_with_ipa_count (ipa);
  gcc_checking_assert (ret.compatible_p (ipa2));
  return ret;
}

/* The profiling runtime uses gcov_type, which is usually 64bit integer.
   Conversions back and forth are used to read the coverage and get it
   into internal representation.  */

profile_count
profile_count::from_gcov_type (gcov_type v, profile_quality quality)
  {
    profile_count ret;
    gcc_checking_assert (v >= 0);
    if (dump_file && v >= (gcov_type)max_count)
      fprintf (dump_file,
	       "Capping gcov count %" PRId64 " to max_count %" PRId64 "\n",
	       (int64_t) v, (int64_t) max_count);
    ret.m_val = MIN (v, (gcov_type)max_count);
    ret.m_quality = quality;
    return ret;
  }

/* COUNT1 times event happens with *THIS probability, COUNT2 times OTHER
   happens with COUNT2 probability.  Return probability that either *THIS or
   OTHER happens.  */

profile_probability
profile_probability::combine_with_count (profile_count count1,
					 profile_probability other,
					 profile_count count2) const
{
  /* If probabilities are same, we are done.
     If counts are nonzero we can distribute accordingly. In remaining
     cases just average the values and hope for the best.  */
  if (*this == other || count1 == count2
      || (count2 == profile_count::zero ()
	  && !(count1 == profile_count::zero ())))
    return *this;
  if (count1 == profile_count::zero () && !(count2 == profile_count::zero ()))
    return other;
  else if (count1.nonzero_p () || count2.nonzero_p ())
    return *this * count1.probability_in (count1 + count2)
	   + other * count2.probability_in (count1 + count2);
  else
    return *this * even () + other * even ();
}

/* Return probability as sreal in range [0, 1].  */

sreal
profile_probability::to_sreal () const
{
  gcc_checking_assert (initialized_p ());
  return ((sreal)m_val) >> (n_bits - 2);
}
