/* Callgraph summary data structure.
   Copyright (C) 2014-2025 Free Software Foundation, Inc.
   Contributed by Martin Liska

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/>.  */

#ifndef GCC_SYMBOL_SUMMARY_H
#define GCC_SYMBOL_SUMMARY_H

/* Base class for function_summary and fast_function_summary classes.  */

template <class T>
class function_summary_base
{
public:
  /* Default construction takes SYMTAB as an argument.  */
  function_summary_base (symbol_table *symtab,
			 cgraph_node_hook symtab_insertion,
			 cgraph_node_hook symtab_removal,
			 cgraph_2node_hook symtab_duplication
			 CXX_MEM_STAT_INFO):
  m_symtab (symtab), m_symtab_insertion (symtab_insertion),
  m_symtab_removal (symtab_removal),
  m_symtab_duplication (symtab_duplication),
  m_symtab_insertion_hook (NULL), m_symtab_duplication_hook (NULL),
  m_allocator ("function summary" PASS_MEM_STAT)
  {
    enable_insertion_hook ();
    m_symtab_removal_hook
      = m_symtab->add_cgraph_removal_hook (m_symtab_removal, this);
    enable_duplication_hook ();
  }

  /* Basic implementation of insert operation.  */
  virtual void insert (cgraph_node *, T *)
  {
    /* In most cases, it makes no sense to create summaries without
       initializing them.  */
    gcc_unreachable ();
  }

  /* Basic implementation of removal operation.  */
  virtual void remove (cgraph_node *, T *) {}

  /* Basic implementation of duplication operation.  */
  virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *)
  {
    /* It makes no sense to not copy anything during duplication.  */
    gcc_unreachable ();
  }

  /* Enable insertion hook invocation.  */
  void enable_insertion_hook ()
  {
    if (m_symtab_insertion_hook == NULL)
      m_symtab_insertion_hook
	= m_symtab->add_cgraph_insertion_hook (m_symtab_insertion, this);
  }

  /* Disable insertion hook invocation.  */
  void disable_insertion_hook ()
  {
    if (m_symtab_insertion_hook != NULL)
      {
	m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
	m_symtab_insertion_hook = NULL;
      }
  }

  /* Enable duplication hook invocation.  */
  void enable_duplication_hook ()
  {
    if (m_symtab_duplication_hook == NULL)
      m_symtab_duplication_hook
	= m_symtab->add_cgraph_duplication_hook (m_symtab_duplication, this);
  }

  /* Enable duplication hook invocation.  */
  void disable_duplication_hook ()
  {
    if (m_symtab_duplication_hook != NULL)
      {
	m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
	m_symtab_duplication_hook = NULL;
      }
  }

protected:
  /* Allocates new data that are stored within map.  */
  T* allocate_new ()
  {
    /* Call gcc_internal_because we do not want to call finalizer for
       a type T.  We call dtor explicitly.  */
    return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
		     : m_allocator.allocate () ;
  }

  /* Release an item that is stored within map.  */
  void release (T *item)
  {
    if (is_ggc ())
      ggc_delete (item);
    else
      m_allocator.remove (item);
  }

  /* Unregister all call-graph hooks.  */
  void unregister_hooks ();

  /* Symbol table the summary is registered to.  */
  symbol_table *m_symtab;

  /* Insertion function defined by a summary.  */
  cgraph_node_hook m_symtab_insertion;
  /* Removal function defined by a summary.  */
  cgraph_node_hook m_symtab_removal;
  /* Duplication function defined by a summary.  */
  cgraph_2node_hook m_symtab_duplication;

  /* Internal summary insertion hook pointer.  */
  cgraph_node_hook_list *m_symtab_insertion_hook;
  /* Internal summary removal hook pointer.  */
  cgraph_node_hook_list *m_symtab_removal_hook;
  /* Internal summary duplication hook pointer.  */
  cgraph_2node_hook_list *m_symtab_duplication_hook;

private:
  /* Return true when the summary uses GGC memory for allocation.  */
  virtual bool is_ggc () = 0;

  /* Object allocator for heap allocation.  */
  object_allocator<T> m_allocator;
};

template <typename T>
void
function_summary_base<T>::unregister_hooks ()
{
  disable_insertion_hook ();
  m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
  disable_duplication_hook ();
}

/* We want to pass just pointer types as argument for function_summary
   template class.  */

template <class T>
class function_summary
{
private:
  function_summary();
};

/* Function summary is a helper class that is used to associate a data structure
   related to a callgraph node.  Typical usage can be seen in IPA passes which
   create a temporary pass-related structures.  The summary class registers
   hooks that are triggered when a new node is inserted, duplicated and deleted.
   A user of a summary class can ovewrite virtual methods than are triggered by
   the summary if such hook is triggered.  Apart from a callgraph node, the user
   is given a data structure tied to the node.

   The function summary class can work both with a heap-allocated memory and
   a memory gained by garbage collected memory.  */

template <class T>
class GTY((user)) function_summary <T *>: public function_summary_base<T>
{
public:
  /* Default construction takes SYMTAB as an argument.  */
  function_summary (symbol_table *symtab, bool ggc = false CXX_MEM_STAT_INFO);

  /* Destructor.  */
  virtual ~function_summary ();

  /* Traverses all summarys with a function F called with
     ARG as argument.  */
  template<typename Arg, bool (*f)(const T &, Arg)>
  void traverse (Arg a) const
  {
    m_map.template traverse <f> (a);
  }

  /* Getter for summary callgraph node pointer.  If a summary for a node
     does not exist it will be created.  */
  T* get_create (cgraph_node *node)
  {
    bool existed;
    T **v = &m_map.get_or_insert (node->get_uid (), &existed);
    if (!existed)
      *v = this->allocate_new ();

    return *v;
  }

  /* Getter for summary callgraph node pointer.  */
  T* get (cgraph_node *node) ATTRIBUTE_PURE
  {
    T **v = m_map.get (node->get_uid ());
    return v == NULL ? NULL : *v;
  }

  /* Remove node from summary.  */
  using function_summary_base<T>::remove;
  void remove (cgraph_node *node)
  {
    int uid = node->get_uid ();
    T **v = m_map.get (uid);
    if (v)
      {
	m_map.remove (uid);
	this->release (*v);
      }
  }

  /* Return true if a summary for the given NODE already exists.  */
  bool exists (cgraph_node *node)
  {
    return m_map.get (node->get_uid ()) != NULL;
  }

  /* Symbol insertion hook that is registered to symbol table.  */
  static void symtab_insertion (cgraph_node *node, void *data);

  /* Symbol removal hook that is registered to symbol table.  */
  static void symtab_removal (cgraph_node *node, void *data);

  /* Symbol duplication hook that is registered to symbol table.  */
  static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
				  void *data);

protected:
  /* Indication if we use ggc summary.  */
  bool m_ggc;

private:
  /* Indication if we use ggc summary.  */
  bool is_ggc () final override
  {
    return m_ggc;
  }

  typedef int_hash <int, 0, -1> map_hash;

  /* Main summary store, where summary ID is used as key.  */
  hash_map <map_hash, T *> m_map;

  template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &);
  template <typename U> friend void gt_pch_nx (function_summary <U *> * const &);
  template <typename U> friend void gt_pch_nx (function_summary <U *> * const &,
      gt_pointer_operator, void *);
};

template <typename T>
function_summary<T *>::function_summary (symbol_table *symtab, bool ggc
					 MEM_STAT_DECL):
  function_summary_base<T> (symtab, function_summary::symtab_insertion,
			    function_summary::symtab_removal,
			    function_summary::symtab_duplication
			    PASS_MEM_STAT),
  m_ggc (ggc), m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT) {}

template <typename T>
function_summary<T *>::~function_summary ()
{
  this->unregister_hooks ();

  /* Release all summaries.  */
  typedef typename hash_map <map_hash, T *>::iterator map_iterator;
  for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
    this->release ((*it).second);
}

template <typename T>
void
function_summary<T *>::symtab_insertion (cgraph_node *node, void *data)
{
  gcc_checking_assert (node->get_uid ());
  function_summary *summary = (function_summary <T *> *) (data);
  summary->insert (node, summary->get_create (node));
}

template <typename T>
void
function_summary<T *>::symtab_removal (cgraph_node *node, void *data)
{
  gcc_checking_assert (node->get_uid ());
  function_summary *summary = (function_summary <T *> *) (data);
  summary->remove (node);
}

template <typename T>
void
function_summary<T *>::symtab_duplication (cgraph_node *node,
					   cgraph_node *node2, void *data)
{
  function_summary *summary = (function_summary <T *> *) (data);
  T *v = summary->get (node);

  if (v)
    summary->duplicate (node, node2, v, summary->get_create (node2));
}

template <typename T>
void
gt_ggc_mx(function_summary<T *>* const &summary)
{
  gcc_checking_assert (summary->m_ggc);
  gt_ggc_mx (&summary->m_map);
}

template <typename T>
void
gt_pch_nx (function_summary<T *> *const &)
{
  gcc_unreachable ();
}

template <typename T>
void
gt_pch_nx (function_summary<T *> *const &, gt_pointer_operator, void *)
{
  gcc_unreachable ();
}

/* Help template from std c++11.  */

template<typename T, typename U>
struct is_same
{
    static const bool value = false;
};

template<typename T>
struct is_same<T,T>  //specialization
{
   static const bool value = true;
};

/* We want to pass just pointer types as argument for fast_function_summary
   template class.  */

template <class T, class V>
class fast_function_summary
{
private:
  fast_function_summary ();
};

/* Function vector summary is a fast implementation of function_summary that
   utilizes vector as primary storage of summaries.  */

template <class T, class V>
class GTY((user)) fast_function_summary <T *, V>
  : public function_summary_base<T>
{
public:
  /* Default construction takes SYMTAB as an argument.  */
  fast_function_summary (symbol_table *symtab CXX_MEM_STAT_INFO);

  /* Destructor.  */
  virtual ~fast_function_summary ();

  /* Traverses all summarys with a function F called with
     ARG as argument.  */
  template<typename Arg, bool (*f)(const T &, Arg)>
  void traverse (Arg a) const
  {
    for (unsigned i = 0; i < m_vector->length (); i++)
      if ((*m_vector[i]) != NULL)
	f ((*m_vector)[i], a);
  }

  /* Getter for summary callgraph node pointer.  If a summary for a node
     does not exist it will be created.  */
  T* get_create (cgraph_node *node)
  {
    int id = node->get_summary_id ();
    if (id == -1)
      id = this->m_symtab->assign_summary_id (node);

    if ((unsigned int)id >= m_vector->length ())
      vec_safe_grow_cleared (m_vector,
			     this->m_symtab->cgraph_max_summary_id);

    if ((*m_vector)[id] == NULL)
      (*m_vector)[id] = this->allocate_new ();

    return (*m_vector)[id];
  }

  /* Getter for summary callgraph node pointer.  */
  T* get (cgraph_node *node) ATTRIBUTE_PURE
  {
    return exists (node) ? (*m_vector)[node->get_summary_id ()] : NULL;
  }

  using function_summary_base<T>::remove;
  void remove (cgraph_node *node)
  {
    if (exists (node))
      {
	int id = node->get_summary_id ();
	this->release ((*m_vector)[id]);
	(*m_vector)[id] = NULL;
      }
  }

  /* Return true if a summary for the given NODE already exists.  */
  bool exists (cgraph_node *node)
  {
    int id = node->get_summary_id ();
    return (id != -1
	    && (unsigned int)id < m_vector->length ()
	    && (*m_vector)[id] != NULL);
  }

  /* Symbol insertion hook that is registered to symbol table.  */
  static void symtab_insertion (cgraph_node *node, void *data);

  /* Symbol removal hook that is registered to symbol table.  */
  static void symtab_removal (cgraph_node *node, void *data);

  /* Symbol duplication hook that is registered to symbol table.  */
  static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
				  void *data);

private:
  bool is_ggc () final override;

  /* Summary is stored in the vector.  */
  vec <T *, V> *m_vector;

  template <typename U> friend void gt_ggc_mx (fast_function_summary <U *, va_gc> * const &);
  template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &);
  template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &,
      gt_pointer_operator, void *);
};

template <typename T, typename V>
fast_function_summary<T *, V>::fast_function_summary (symbol_table *symtab
						      MEM_STAT_DECL):
  function_summary_base<T> (symtab,
			    fast_function_summary::symtab_insertion,
			    fast_function_summary::symtab_removal,
			    fast_function_summary::symtab_duplication
			    PASS_MEM_STAT), m_vector (NULL)
{
  vec_alloc (m_vector, 13 PASS_MEM_STAT);
}

template <typename T, typename V>
fast_function_summary<T *, V>::~fast_function_summary ()
{
  this->unregister_hooks ();

  /* Release all summaries.  */
  for (unsigned i = 0; i < m_vector->length (); i++)
    if ((*m_vector)[i] != NULL)
      this->release ((*m_vector)[i]);
  vec_free (m_vector);
}

template <typename T, typename V>
void
fast_function_summary<T *, V>::symtab_insertion (cgraph_node *node, void *data)
{
  gcc_checking_assert (node->get_uid ());
  fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
  summary->insert (node, summary->get_create (node));
}

template <typename T, typename V>
void
fast_function_summary<T *, V>::symtab_removal (cgraph_node *node, void *data)
{
  gcc_checking_assert (node->get_uid ());
  fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);

  if (summary->exists (node))
    summary->remove (node);
}

template <typename T, typename V>
void
fast_function_summary<T *, V>::symtab_duplication (cgraph_node *node,
						   cgraph_node *node2,
						   void *data)
{
  fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
  T *v = summary->get (node);

  if (v)
    {
      T *duplicate = summary->get_create (node2);
      summary->duplicate (node, node2, v, duplicate);
    }
}

template <typename T, typename V>
inline bool
fast_function_summary<T *, V>::is_ggc ()
{
  return is_same<V, va_gc>::value;
}

template <typename T>
void
gt_ggc_mx (fast_function_summary<T *, va_heap>* const &)
{
}

template <typename T>
void
gt_pch_nx (fast_function_summary<T *, va_heap>* const &)
{
}

template <typename T>
void
gt_pch_nx (fast_function_summary<T *, va_heap>* const&, gt_pointer_operator,
	   void *)
{
}

template <typename T>
void
gt_ggc_mx (fast_function_summary<T *, va_gc>* const &summary)
{
  ggc_test_and_set_mark (summary->m_vector);
  gt_ggc_mx (summary->m_vector);
}

template <typename T>
void
gt_pch_nx (fast_function_summary<T *, va_gc> *const &)
{
  gcc_unreachable ();
}

template <typename T>
void
gt_pch_nx (fast_function_summary<T *, va_gc> *const &, gt_pointer_operator,
	   void *)
{
  gcc_unreachable ();
}

/* Base class for call_summary and fast_call_summary classes.  */

template <class T>
class call_summary_base
{
public:
  /* Default construction takes SYMTAB as an argument.  */
  call_summary_base (symbol_table *symtab, cgraph_edge_hook symtab_removal,
		     cgraph_2edge_hook symtab_duplication CXX_MEM_STAT_INFO):
  m_symtab (symtab), m_symtab_removal (symtab_removal),
  m_symtab_duplication (symtab_duplication), m_symtab_duplication_hook (NULL),
  m_initialize_when_cloning (false),
  m_allocator ("call summary" PASS_MEM_STAT)
  {
    m_symtab_removal_hook
      = m_symtab->add_edge_removal_hook (m_symtab_removal, this);
    enable_duplication_hook ();
  }

  /* Basic implementation of removal operation.  */
  virtual void remove (cgraph_edge *, T *) {}

  /* Basic implementation of duplication operation.  */
  virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *)
  {
    gcc_unreachable ();
  }

  /* Enable duplication hook invocation.  */
  void enable_duplication_hook ()
  {
    if (m_symtab_duplication_hook == NULL)
      m_symtab_duplication_hook
	= m_symtab->add_edge_duplication_hook (m_symtab_duplication,
					       this);
  }

  /* Enable duplication hook invocation.  */
  void disable_duplication_hook ()
  {
    if (m_symtab_duplication_hook != NULL)
      {
	m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook);
	m_symtab_duplication_hook = NULL;
      }
  }

protected:
  /* Allocates new data that are stored within map.  */
  T* allocate_new ()
  {
    /* Call gcc_internal_because we do not want to call finalizer for
       a type T.  We call dtor explicitly.  */
    return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
		     : m_allocator.allocate ();
  }

  /* Release an item that is stored within map.  */
  void release (T *item)
  {
    if (is_ggc ())
      ggc_delete (item);
    else
      m_allocator.remove (item);
  }

  /* Unregister all call-graph hooks.  */
  void unregister_hooks ();

  /* Symbol table the summary is registered to.  */
  symbol_table *m_symtab;

  /* Removal function defined by a summary.  */
  cgraph_edge_hook m_symtab_removal;
  /* Duplication function defined by a summary.  */
  cgraph_2edge_hook m_symtab_duplication;

  /* Internal summary removal hook pointer.  */
  cgraph_edge_hook_list *m_symtab_removal_hook;
  /* Internal summary duplication hook pointer.  */
  cgraph_2edge_hook_list *m_symtab_duplication_hook;
  /* Initialize summary for an edge that is cloned.  */
  bool m_initialize_when_cloning;

private:
  /* Return true when the summary uses GGC memory for allocation.  */
  virtual bool is_ggc () = 0;

  /* Object allocator for heap allocation.  */
  object_allocator<T> m_allocator;
};

template <typename T>
void
call_summary_base<T>::unregister_hooks ()
{
  m_symtab->remove_edge_removal_hook (m_symtab_removal_hook);
  disable_duplication_hook ();
}

/* An impossible class templated by non-pointers so, which makes sure that only
   summaries gathering pointers can be created.  */

template <class T>
class call_summary
{
private:
  call_summary ();
};

/* Class to store auxiliary information about call graph edges.  */

template <class T>
class GTY((user)) call_summary <T *>: public call_summary_base<T>
{
public:
  /* Default construction takes SYMTAB as an argument.  */
  call_summary (symbol_table *symtab, bool ggc = false
		CXX_MEM_STAT_INFO)
  : call_summary_base<T> (symtab, call_summary::symtab_removal,
			  call_summary::symtab_duplication PASS_MEM_STAT),
    m_ggc (ggc), m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT) {}

  /* Destructor.  */
  virtual ~call_summary ();

  /* Traverses all summarys with an edge E called with
     ARG as argument.  */
  template<typename Arg, bool (*f)(const T &, Arg)>
  void traverse (Arg a) const
  {
    m_map.template traverse <f> (a);
  }

  /* Getter for summary callgraph edge pointer.
     If a summary for an edge does not exist, it will be created.  */
  T* get_create (cgraph_edge *edge)
  {
    bool existed;
    T **v = &m_map.get_or_insert (edge->get_uid (), &existed);
    if (!existed)
      *v = this->allocate_new ();

    return *v;
  }

  /* Getter for summary callgraph edge pointer.  */
  T* get (cgraph_edge *edge) ATTRIBUTE_PURE
  {
    T **v = m_map.get (edge->get_uid ());
    return v == NULL ? NULL : *v;
  }

  /* Remove edge from summary.  */
  using call_summary_base<T>::remove;
  void remove (cgraph_edge *edge)
  {
    int uid = edge->get_uid ();
    T **v = m_map.get (uid);
    if (v)
      {
	m_map.remove (uid);
	this->release (*v);
      }
  }

  /* Return true if a summary for the given EDGE already exists.  */
  bool exists (cgraph_edge *edge)
  {
    return m_map.get (edge->get_uid ()) != NULL;
  }

  /* Symbol removal hook that is registered to symbol table.  */
  static void symtab_removal (cgraph_edge *edge, void *data);

  /* Symbol duplication hook that is registered to symbol table.  */
  static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
				  void *data);

protected:
  /* Indication if we use ggc summary.  */
  bool m_ggc;

private:
  /* Indication if we use ggc summary.  */
  bool is_ggc () final override
  {
    return m_ggc;
  }

  typedef int_hash <int, 0, -1> map_hash;

  /* Main summary store, where summary ID is used as key.  */
  hash_map <map_hash, T *> m_map;

  template <typename U> friend void gt_ggc_mx (call_summary <U *> * const &);
  template <typename U> friend void gt_pch_nx (call_summary <U *> * const &);
  template <typename U> friend void gt_pch_nx (call_summary <U *> * const &,
      gt_pointer_operator, void *);
};

template <typename T>
call_summary<T *>::~call_summary ()
{
  this->unregister_hooks ();

  /* Release all summaries.  */
  typedef typename hash_map <map_hash, T *>::iterator map_iterator;
  for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
    this->release ((*it).second);
}

template <typename T>
void
call_summary<T *>::symtab_removal (cgraph_edge *edge, void *data)
{
  call_summary *summary = (call_summary <T *> *) (data);
  summary->remove (edge);
}

template <typename T>
void
call_summary<T *>::symtab_duplication (cgraph_edge *edge1,
				       cgraph_edge *edge2, void *data)
{
  call_summary *summary = (call_summary <T *> *) (data);
  T *edge1_summary = NULL;

  if (summary->m_initialize_when_cloning)
    edge1_summary = summary->get_create (edge1);
  else
    edge1_summary = summary->get (edge1);

  if (edge1_summary)
    summary->duplicate (edge1, edge2, edge1_summary,
			summary->get_create (edge2));
}

template <typename T>
void
gt_ggc_mx(call_summary<T *>* const &summary)
{
  gcc_checking_assert (summary->m_ggc);
  gt_ggc_mx (&summary->m_map);
}

template <typename T>
void
gt_pch_nx (call_summary<T *> *const &)
{
  gcc_unreachable ();
}

template <typename T>
void
gt_pch_nx (call_summary<T *> *const &, gt_pointer_operator, void *)
{
  gcc_unreachable ();
}

/* We want to pass just pointer types as argument for fast_call_summary
   template class.  */

template <class T, class V>
class fast_call_summary
{
private:
  fast_call_summary ();
};

/* Call vector summary is a fast implementation of call_summary that
   utilizes vector as primary storage of summaries.  */

template <class T, class V>
class GTY((user)) fast_call_summary <T *, V>: public call_summary_base<T>
{
public:
  /* Default construction takes SYMTAB as an argument.  */
  fast_call_summary (symbol_table *symtab CXX_MEM_STAT_INFO)
  : call_summary_base<T> (symtab, fast_call_summary::symtab_removal,
			  fast_call_summary::symtab_duplication PASS_MEM_STAT),
    m_vector (NULL)
  {
    vec_alloc (m_vector, 13 PASS_MEM_STAT);
  }

  /* Destructor.  */
  virtual ~fast_call_summary ();

  /* Traverses all summarys with an edge F called with
     ARG as argument.  */
  template<typename Arg, bool (*f)(const T &, Arg)>
  void traverse (Arg a) const
  {
    for (unsigned i = 0; i < m_vector->length (); i++)
      if ((*m_vector[i]) != NULL)
	f ((*m_vector)[i], a);
  }

  /* Getter for summary callgraph edge pointer.
     If a summary for an edge does not exist, it will be created.  */
  T* get_create (cgraph_edge *edge)
  {
    int id = edge->get_summary_id ();
    if (id == -1)
      id = this->m_symtab->assign_summary_id (edge);

    if ((unsigned)id >= m_vector->length ())
      vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id);

    if ((*m_vector)[id] == NULL)
      (*m_vector)[id] = this->allocate_new ();

    return (*m_vector)[id];
  }

  /* Getter for summary callgraph edge pointer.  */
  T* get (cgraph_edge *edge) ATTRIBUTE_PURE
  {
    return exists (edge) ? (*m_vector)[edge->get_summary_id ()] : NULL;
  }

  /* Remove edge from summary.  */
  using call_summary_base<T>::remove;
  void remove (cgraph_edge *edge)
  {
    if (exists (edge))
      {
	int id = edge->get_summary_id ();
	this->release ((*m_vector)[id]);
	(*m_vector)[id] = NULL;
      }
  }

  /* Return true if a summary for the given EDGE already exists.  */
  bool exists (cgraph_edge *edge)
  {
    int id = edge->get_summary_id ();
    return (id != -1
	    && (unsigned)id < m_vector->length ()
	    && (*m_vector)[id] != NULL);
  }

  /* Symbol removal hook that is registered to symbol table.  */
  static void symtab_removal (cgraph_edge *edge, void *data);

  /* Symbol duplication hook that is registered to symbol table.  */
  static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
				  void *data);

private:
  bool is_ggc () final override;

  /* Summary is stored in the vector.  */
  vec <T *, V> *m_vector;

  template <typename U> friend void gt_ggc_mx (fast_call_summary <U *, va_gc> * const &);
  template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &);
  template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &,
      gt_pointer_operator, void *);
};

template <typename T, typename V>
fast_call_summary<T *, V>::~fast_call_summary ()
{
  this->unregister_hooks ();

  /* Release all summaries.  */
  for (unsigned i = 0; i < m_vector->length (); i++)
    if ((*m_vector)[i] != NULL)
      this->release ((*m_vector)[i]);
  vec_free (m_vector);
}

template <typename T, typename V>
void
fast_call_summary<T *, V>::symtab_removal (cgraph_edge *edge, void *data)
{
  fast_call_summary *summary = (fast_call_summary <T *, V> *) (data);
  summary->remove (edge);
}

template <typename T, typename V>
void
fast_call_summary<T *, V>::symtab_duplication (cgraph_edge *edge1,
						 cgraph_edge *edge2, void *data)
{
  fast_call_summary *summary = (fast_call_summary <T *, V> *) (data);
  T *edge1_summary = NULL;

  if (summary->m_initialize_when_cloning)
    edge1_summary = summary->get_create (edge1);
  else
    edge1_summary = summary->get (edge1);

  if (edge1_summary)
    {
      T *duplicate = summary->get_create (edge2);
      summary->duplicate (edge1, edge2, edge1_summary, duplicate);
    }
}

template <typename T, typename V>
inline bool
fast_call_summary<T *, V>::is_ggc ()
{
  return is_same<V, va_gc>::value;
}

template <typename T>
void
gt_ggc_mx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED)
{
}

template <typename T>
void
gt_pch_nx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED)
{
}

template <typename T>
void
gt_pch_nx (fast_call_summary<T *, va_heap>* const& summary ATTRIBUTE_UNUSED,
	   gt_pointer_operator op ATTRIBUTE_UNUSED,
	   void *cookie ATTRIBUTE_UNUSED)
{
}

template <typename T>
void
gt_ggc_mx (fast_call_summary<T *, va_gc>* const &summary)
{
  ggc_test_and_set_mark (summary->m_vector);
  gt_ggc_mx (&summary->m_vector);
}

template <typename T>
void
gt_pch_nx (fast_call_summary<T *, va_gc> *const &)
{
  gcc_unreachable ();
}

template <typename T>
void
gt_pch_nx (fast_call_summary<T *, va_gc> *const &, gt_pointer_operator, void *)
{
  gcc_unreachable ();
}

#endif  /* GCC_SYMBOL_SUMMARY_H  */
