/* A class to encapsulate decisions about how the analysis should happen.
   Copyright (C) 2019-2021 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

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 "tree.h"
#include "options.h"
#include "cgraph.h"
#include "timevar.h"
#include "ipa-utils.h"
#include "function.h"
#include "json.h"
#include "analyzer/analyzer.h"
#include "diagnostic-core.h"
#include "analyzer/analyzer-logging.h"
#include "analyzer/analysis-plan.h"
#include "ordered-hash-map.h"
#include "options.h"
#include "cgraph.h"
#include "function.h"
#include "cfg.h"
#include "basic-block.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "digraph.h"
#include "analyzer/supergraph.h"

#if ENABLE_ANALYZER

/* class analysis_plan.  */

/* analysis_plan's ctor.  */

analysis_plan::analysis_plan (const supergraph &sg, logger *logger)
: log_user (logger), m_sg (sg),
  m_cgraph_node_postorder (XCNEWVEC (struct cgraph_node *,
				     symtab->cgraph_count)),
  m_index_by_uid (symtab->cgraph_max_uid)
{
  LOG_SCOPE (logger);
  auto_timevar time (TV_ANALYZER_PLAN);

  m_num_cgraph_nodes = ipa_reverse_postorder (m_cgraph_node_postorder);
  gcc_assert (m_num_cgraph_nodes == symtab->cgraph_count);
  if (get_logger_file ())
    ipa_print_order (get_logger_file (),
		     "analysis_plan", m_cgraph_node_postorder,
		     m_num_cgraph_nodes);

  /* Populate m_index_by_uid.  */
  for (int i = 0; i < symtab->cgraph_max_uid; i++)
    m_index_by_uid.quick_push (-1);
  for (int i = 0; i < m_num_cgraph_nodes; i++)
    {
      gcc_assert (m_cgraph_node_postorder[i]->get_uid ()
		  < symtab->cgraph_max_uid);
      m_index_by_uid[m_cgraph_node_postorder[i]->get_uid ()] = i;
    }
}

/* analysis_plan's dtor.  */

analysis_plan::~analysis_plan ()
{
  free (m_cgraph_node_postorder);
}

/* Comparator for use by the exploded_graph's worklist, to order FUN_A
   and FUN_B so that functions that are to be summarized are visited
   before the summary is needed (based on a sort of the callgraph).  */

int
analysis_plan::cmp_function (function *fun_a, function *fun_b) const
{
  cgraph_node *node_a = cgraph_node::get (fun_a->decl);
  cgraph_node *node_b = cgraph_node::get (fun_b->decl);

  int idx_a = m_index_by_uid[node_a->get_uid ()];
  int idx_b = m_index_by_uid[node_b->get_uid ()];

  return idx_b - idx_a;
}

/* Return true if the call EDGE should be analyzed using a call summary.
   Return false if it should be analyzed using a full call and return.  */

bool
analysis_plan::use_summary_p (const cgraph_edge *edge) const
{
  /* Don't use call summaries if -fno-analyzer-call-summaries.  */
  if (!flag_analyzer_call_summaries)
    return false;

  /* Don't use call summaries if there is no callgraph edge */
  if (!edge || !edge->callee)
    return false;

  /* TODO: don't count callsites each time.  */
  int num_call_sites = 0;
  const cgraph_node *callee = edge->callee;
  for (cgraph_edge *edge = callee->callers; edge; edge = edge->next_caller)
    ++num_call_sites;

  /* Don't use a call summary if there's only one call site.  */
  if (num_call_sites <= 1)
    return false;

  /* Require the callee to be sufficiently complex to be worth
     summarizing.  */
  const function *fun
    = const_cast <cgraph_node *> (callee)->ultimate_alias_target ()->get_fun ();
  /* TODO(stage1): can ultimate_alias_target be made const?  */

  if ((int)m_sg.get_num_snodes (fun)
      < param_analyzer_min_snodes_for_call_summary)
    return false;

  return true;
}

#endif /* #if ENABLE_ANALYZER */
