/* Callgraph summary data structure.
   Copyright (C) 2014-2022 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);
  }

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