Home | History | Annotate | Line # | Download | only in gcc
symbol-summary.h revision 1.7
      1  1.1  mrg /* Callgraph summary data structure.
      2  1.6  mrg    Copyright (C) 2014-2020 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Martin Liska
      4  1.1  mrg 
      5  1.1  mrg This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      8  1.1  mrg the terms of the GNU General Public License as published by the Free
      9  1.1  mrg Software Foundation; either version 3, or (at your option) any later
     10  1.1  mrg version.
     11  1.1  mrg 
     12  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  1.1  mrg for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License
     18  1.1  mrg along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg #ifndef GCC_SYMBOL_SUMMARY_H
     22  1.1  mrg #define GCC_SYMBOL_SUMMARY_H
     23  1.1  mrg 
     24  1.5  mrg /* Base class for function_summary and fast_function_summary classes.  */
     25  1.1  mrg 
     26  1.1  mrg template <class T>
     27  1.5  mrg class function_summary_base
     28  1.1  mrg {
     29  1.1  mrg public:
     30  1.1  mrg   /* Default construction takes SYMTAB as an argument.  */
     31  1.6  mrg   function_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO):
     32  1.6  mrg   m_symtab (symtab),
     33  1.6  mrg   m_insertion_enabled (true),
     34  1.6  mrg   m_allocator ("function summary" PASS_MEM_STAT)
     35  1.5  mrg   {}
     36  1.1  mrg 
     37  1.1  mrg   /* Basic implementation of insert operation.  */
     38  1.1  mrg   virtual void insert (cgraph_node *, T *) {}
     39  1.1  mrg 
     40  1.1  mrg   /* Basic implementation of removal operation.  */
     41  1.1  mrg   virtual void remove (cgraph_node *, T *) {}
     42  1.1  mrg 
     43  1.1  mrg   /* Basic implementation of duplication operation.  */
     44  1.1  mrg   virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {}
     45  1.1  mrg 
     46  1.5  mrg   /* Enable insertion hook invocation.  */
     47  1.5  mrg   void enable_insertion_hook ()
     48  1.5  mrg   {
     49  1.5  mrg     m_insertion_enabled = true;
     50  1.5  mrg   }
     51  1.5  mrg 
     52  1.5  mrg   /* Enable insertion hook invocation.  */
     53  1.5  mrg   void disable_insertion_hook ()
     54  1.5  mrg   {
     55  1.5  mrg     m_insertion_enabled = false;
     56  1.5  mrg   }
     57  1.5  mrg 
     58  1.5  mrg protected:
     59  1.1  mrg   /* Allocates new data that are stored within map.  */
     60  1.1  mrg   T* allocate_new ()
     61  1.1  mrg   {
     62  1.3  mrg     /* Call gcc_internal_because we do not want to call finalizer for
     63  1.3  mrg        a type T.  We call dtor explicitly.  */
     64  1.6  mrg     return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
     65  1.6  mrg 		     : m_allocator.allocate () ;
     66  1.1  mrg   }
     67  1.1  mrg 
     68  1.1  mrg   /* Release an item that is stored within map.  */
     69  1.1  mrg   void release (T *item)
     70  1.1  mrg   {
     71  1.5  mrg     if (is_ggc ())
     72  1.6  mrg       ggc_delete (item);
     73  1.1  mrg     else
     74  1.6  mrg       m_allocator.remove (item);
     75  1.1  mrg   }
     76  1.1  mrg 
     77  1.5  mrg   /* Unregister all call-graph hooks.  */
     78  1.5  mrg   void unregister_hooks ();
     79  1.5  mrg 
     80  1.5  mrg   /* Internal summary insertion hook pointer.  */
     81  1.5  mrg   cgraph_node_hook_list *m_symtab_insertion_hook;
     82  1.5  mrg   /* Internal summary removal hook pointer.  */
     83  1.5  mrg   cgraph_node_hook_list *m_symtab_removal_hook;
     84  1.5  mrg   /* Internal summary duplication hook pointer.  */
     85  1.5  mrg   cgraph_2node_hook_list *m_symtab_duplication_hook;
     86  1.5  mrg   /* Symbol table the summary is registered to.  */
     87  1.5  mrg   symbol_table *m_symtab;
     88  1.5  mrg 
     89  1.5  mrg   /* Indicates if insertion hook is enabled.  */
     90  1.5  mrg   bool m_insertion_enabled;
     91  1.5  mrg 
     92  1.5  mrg private:
     93  1.5  mrg   /* Return true when the summary uses GGC memory for allocation.  */
     94  1.5  mrg   virtual bool is_ggc () = 0;
     95  1.6  mrg 
     96  1.6  mrg   /* Object allocator for heap allocation.  */
     97  1.6  mrg   object_allocator<T> m_allocator;
     98  1.5  mrg };
     99  1.5  mrg 
    100  1.5  mrg template <typename T>
    101  1.5  mrg void
    102  1.5  mrg function_summary_base<T>::unregister_hooks ()
    103  1.5  mrg {
    104  1.5  mrg   m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
    105  1.5  mrg   m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
    106  1.5  mrg   m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
    107  1.5  mrg }
    108  1.5  mrg 
    109  1.5  mrg /* We want to pass just pointer types as argument for function_summary
    110  1.5  mrg    template class.  */
    111  1.5  mrg 
    112  1.5  mrg template <class T>
    113  1.5  mrg class function_summary
    114  1.5  mrg {
    115  1.5  mrg private:
    116  1.5  mrg   function_summary();
    117  1.5  mrg };
    118  1.5  mrg 
    119  1.5  mrg /* Function summary is a helper class that is used to associate a data structure
    120  1.5  mrg    related to a callgraph node.  Typical usage can be seen in IPA passes which
    121  1.5  mrg    create a temporary pass-related structures.  The summary class registers
    122  1.5  mrg    hooks that are triggered when a new node is inserted, duplicated and deleted.
    123  1.5  mrg    A user of a summary class can ovewrite virtual methods than are triggered by
    124  1.5  mrg    the summary if such hook is triggered.  Apart from a callgraph node, the user
    125  1.5  mrg    is given a data structure tied to the node.
    126  1.5  mrg 
    127  1.5  mrg    The function summary class can work both with a heap-allocated memory and
    128  1.5  mrg    a memory gained by garbage collected memory.  */
    129  1.5  mrg 
    130  1.5  mrg template <class T>
    131  1.5  mrg class GTY((user)) function_summary <T *>: public function_summary_base<T>
    132  1.5  mrg {
    133  1.5  mrg public:
    134  1.5  mrg   /* Default construction takes SYMTAB as an argument.  */
    135  1.6  mrg   function_summary (symbol_table *symtab, bool ggc = false CXX_MEM_STAT_INFO);
    136  1.5  mrg 
    137  1.5  mrg   /* Destructor.  */
    138  1.6  mrg   virtual ~function_summary ();
    139  1.1  mrg 
    140  1.5  mrg   /* Traverses all summarys with a function F called with
    141  1.5  mrg      ARG as argument.  */
    142  1.5  mrg   template<typename Arg, bool (*f)(const T &, Arg)>
    143  1.5  mrg   void traverse (Arg a) const
    144  1.4  mrg   {
    145  1.7  mrg     m_map.template traverse <f> (a);
    146  1.4  mrg   }
    147  1.4  mrg 
    148  1.5  mrg   /* Getter for summary callgraph node pointer.  If a summary for a node
    149  1.5  mrg      does not exist it will be created.  */
    150  1.5  mrg   T* get_create (cgraph_node *node)
    151  1.1  mrg   {
    152  1.5  mrg     bool existed;
    153  1.5  mrg     T **v = &m_map.get_or_insert (node->get_uid (), &existed);
    154  1.5  mrg     if (!existed)
    155  1.5  mrg       *v = this->allocate_new ();
    156  1.1  mrg 
    157  1.5  mrg     return *v;
    158  1.1  mrg   }
    159  1.1  mrg 
    160  1.5  mrg   /* Getter for summary callgraph node pointer.  */
    161  1.5  mrg   T* get (cgraph_node *node) ATTRIBUTE_PURE
    162  1.1  mrg   {
    163  1.5  mrg     T **v = m_map.get (node->get_uid ());
    164  1.5  mrg     return v == NULL ? NULL : *v;
    165  1.1  mrg   }
    166  1.1  mrg 
    167  1.5  mrg   /* Remove node from summary.  */
    168  1.5  mrg   using function_summary_base<T>::remove;
    169  1.5  mrg   void remove (cgraph_node *node)
    170  1.1  mrg   {
    171  1.5  mrg     int uid = node->get_uid ();
    172  1.5  mrg     T **v = m_map.get (uid);
    173  1.1  mrg     if (v)
    174  1.1  mrg       {
    175  1.5  mrg 	m_map.remove (uid);
    176  1.5  mrg 	this->release (*v);
    177  1.1  mrg       }
    178  1.1  mrg   }
    179  1.1  mrg 
    180  1.5  mrg   /* Return true if a summary for the given NODE already exists.  */
    181  1.5  mrg   bool exists (cgraph_node *node)
    182  1.1  mrg   {
    183  1.5  mrg     return m_map.get (node->get_uid ()) != NULL;
    184  1.5  mrg   }
    185  1.5  mrg 
    186  1.5  mrg   /* Symbol insertion hook that is registered to symbol table.  */
    187  1.5  mrg   static void symtab_insertion (cgraph_node *node, void *data);
    188  1.1  mrg 
    189  1.5  mrg   /* Symbol removal hook that is registered to symbol table.  */
    190  1.5  mrg   static void symtab_removal (cgraph_node *node, void *data);
    191  1.1  mrg 
    192  1.5  mrg   /* Symbol duplication hook that is registered to symbol table.  */
    193  1.5  mrg   static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
    194  1.5  mrg 				  void *data);
    195  1.1  mrg 
    196  1.1  mrg protected:
    197  1.1  mrg   /* Indication if we use ggc summary.  */
    198  1.1  mrg   bool m_ggc;
    199  1.1  mrg 
    200  1.1  mrg private:
    201  1.5  mrg   /* Indication if we use ggc summary.  */
    202  1.5  mrg   virtual bool is_ggc ()
    203  1.1  mrg   {
    204  1.5  mrg     return m_ggc;
    205  1.5  mrg   }
    206  1.1  mrg 
    207  1.5  mrg   typedef int_hash <int, 0, -1> map_hash;
    208  1.1  mrg 
    209  1.1  mrg   /* Main summary store, where summary ID is used as key.  */
    210  1.3  mrg   hash_map <map_hash, T *> m_map;
    211  1.1  mrg 
    212  1.1  mrg   template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &);
    213  1.1  mrg   template <typename U> friend void gt_pch_nx (function_summary <U *> * const &);
    214  1.1  mrg   template <typename U> friend void gt_pch_nx (function_summary <U *> * const &,
    215  1.1  mrg       gt_pointer_operator, void *);
    216  1.1  mrg };
    217  1.1  mrg 
    218  1.1  mrg template <typename T>
    219  1.6  mrg function_summary<T *>::function_summary (symbol_table *symtab, bool ggc
    220  1.6  mrg 					 MEM_STAT_DECL):
    221  1.6  mrg   function_summary_base<T> (symtab PASS_MEM_STAT), m_ggc (ggc),
    222  1.6  mrg   m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT)
    223  1.5  mrg {
    224  1.5  mrg   this->m_symtab_insertion_hook
    225  1.5  mrg     = this->m_symtab->add_cgraph_insertion_hook (function_summary::symtab_insertion,
    226  1.5  mrg 						 this);
    227  1.5  mrg   this->m_symtab_removal_hook
    228  1.5  mrg     = this->m_symtab->add_cgraph_removal_hook (function_summary::symtab_removal,
    229  1.5  mrg 					       this);
    230  1.5  mrg   this->m_symtab_duplication_hook
    231  1.5  mrg     = this->m_symtab->add_cgraph_duplication_hook (function_summary::symtab_duplication,
    232  1.5  mrg 						   this);
    233  1.5  mrg }
    234  1.5  mrg 
    235  1.5  mrg template <typename T>
    236  1.6  mrg function_summary<T *>::~function_summary ()
    237  1.5  mrg {
    238  1.5  mrg   this->unregister_hooks ();
    239  1.5  mrg 
    240  1.5  mrg   /* Release all summaries.  */
    241  1.5  mrg   typedef typename hash_map <map_hash, T *>::iterator map_iterator;
    242  1.5  mrg   for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
    243  1.5  mrg     this->release ((*it).second);
    244  1.5  mrg }
    245  1.5  mrg 
    246  1.5  mrg template <typename T>
    247  1.5  mrg void
    248  1.5  mrg function_summary<T *>::symtab_insertion (cgraph_node *node, void *data)
    249  1.5  mrg {
    250  1.5  mrg   gcc_checking_assert (node->get_uid ());
    251  1.5  mrg   function_summary *summary = (function_summary <T *> *) (data);
    252  1.5  mrg 
    253  1.5  mrg   if (summary->m_insertion_enabled)
    254  1.5  mrg     summary->insert (node, summary->get_create (node));
    255  1.5  mrg }
    256  1.5  mrg 
    257  1.5  mrg template <typename T>
    258  1.5  mrg void
    259  1.5  mrg function_summary<T *>::symtab_removal (cgraph_node *node, void *data)
    260  1.5  mrg {
    261  1.5  mrg   gcc_checking_assert (node->get_uid ());
    262  1.5  mrg   function_summary *summary = (function_summary <T *> *) (data);
    263  1.5  mrg   summary->remove (node);
    264  1.5  mrg }
    265  1.5  mrg 
    266  1.5  mrg template <typename T>
    267  1.5  mrg void
    268  1.5  mrg function_summary<T *>::symtab_duplication (cgraph_node *node,
    269  1.5  mrg 					   cgraph_node *node2, void *data)
    270  1.5  mrg {
    271  1.5  mrg   function_summary *summary = (function_summary <T *> *) (data);
    272  1.5  mrg   T *v = summary->get (node);
    273  1.5  mrg 
    274  1.5  mrg   if (v)
    275  1.5  mrg     summary->duplicate (node, node2, v, summary->get_create (node2));
    276  1.5  mrg }
    277  1.5  mrg 
    278  1.5  mrg template <typename T>
    279  1.1  mrg void
    280  1.1  mrg gt_ggc_mx(function_summary<T *>* const &summary)
    281  1.1  mrg {
    282  1.1  mrg   gcc_checking_assert (summary->m_ggc);
    283  1.1  mrg   gt_ggc_mx (&summary->m_map);
    284  1.1  mrg }
    285  1.1  mrg 
    286  1.1  mrg template <typename T>
    287  1.1  mrg void
    288  1.6  mrg gt_pch_nx (function_summary<T *> *const &)
    289  1.1  mrg {
    290  1.6  mrg   gcc_unreachable ();
    291  1.1  mrg }
    292  1.1  mrg 
    293  1.1  mrg template <typename T>
    294  1.1  mrg void
    295  1.6  mrg gt_pch_nx (function_summary<T *> *const &, gt_pointer_operator, void *)
    296  1.1  mrg {
    297  1.6  mrg   gcc_unreachable ();
    298  1.1  mrg }
    299  1.1  mrg 
    300  1.5  mrg /* Help template from std c++11.  */
    301  1.5  mrg 
    302  1.5  mrg template<typename T, typename U>
    303  1.5  mrg struct is_same
    304  1.5  mrg {
    305  1.5  mrg     static const bool value = false;
    306  1.5  mrg };
    307  1.5  mrg 
    308  1.5  mrg template<typename T>
    309  1.5  mrg struct is_same<T,T>  //specialization
    310  1.5  mrg {
    311  1.5  mrg    static const bool value = true;
    312  1.5  mrg };
    313  1.5  mrg 
    314  1.5  mrg /* We want to pass just pointer types as argument for fast_function_summary
    315  1.5  mrg    template class.  */
    316  1.4  mrg 
    317  1.5  mrg template <class T, class V>
    318  1.5  mrg class fast_function_summary
    319  1.4  mrg {
    320  1.4  mrg private:
    321  1.5  mrg   fast_function_summary ();
    322  1.4  mrg };
    323  1.4  mrg 
    324  1.5  mrg /* Function vector summary is a fast implementation of function_summary that
    325  1.5  mrg    utilizes vector as primary storage of summaries.  */
    326  1.4  mrg 
    327  1.5  mrg template <class T, class V>
    328  1.5  mrg class GTY((user)) fast_function_summary <T *, V>
    329  1.5  mrg   : public function_summary_base<T>
    330  1.4  mrg {
    331  1.4  mrg public:
    332  1.4  mrg   /* Default construction takes SYMTAB as an argument.  */
    333  1.6  mrg   fast_function_summary (symbol_table *symtab CXX_MEM_STAT_INFO);
    334  1.5  mrg 
    335  1.5  mrg   /* Destructor.  */
    336  1.6  mrg   virtual ~fast_function_summary ();
    337  1.5  mrg 
    338  1.5  mrg   /* Traverses all summarys with a function F called with
    339  1.5  mrg      ARG as argument.  */
    340  1.5  mrg   template<typename Arg, bool (*f)(const T &, Arg)>
    341  1.5  mrg   void traverse (Arg a) const
    342  1.4  mrg   {
    343  1.5  mrg     for (unsigned i = 0; i < m_vector->length (); i++)
    344  1.5  mrg       if ((*m_vector[i]) != NULL)
    345  1.6  mrg 	f ((*m_vector)[i], a);
    346  1.4  mrg   }
    347  1.4  mrg 
    348  1.5  mrg   /* Getter for summary callgraph node pointer.  If a summary for a node
    349  1.5  mrg      does not exist it will be created.  */
    350  1.5  mrg   T* get_create (cgraph_node *node)
    351  1.4  mrg   {
    352  1.5  mrg     int id = node->get_summary_id ();
    353  1.5  mrg     if (id == -1)
    354  1.5  mrg       id = this->m_symtab->assign_summary_id (node);
    355  1.5  mrg 
    356  1.5  mrg     if ((unsigned int)id >= m_vector->length ())
    357  1.6  mrg       {
    358  1.6  mrg 	int newlen = this->m_symtab->cgraph_max_summary_id;
    359  1.6  mrg 	vec_safe_reserve (m_vector, newlen - m_vector->length ());
    360  1.6  mrg 	m_vector->quick_grow_cleared (newlen);
    361  1.6  mrg       }
    362  1.5  mrg 
    363  1.5  mrg     if ((*m_vector)[id] == NULL)
    364  1.5  mrg       (*m_vector)[id] = this->allocate_new ();
    365  1.4  mrg 
    366  1.5  mrg     return (*m_vector)[id];
    367  1.5  mrg   }
    368  1.4  mrg 
    369  1.5  mrg   /* Getter for summary callgraph node pointer.  */
    370  1.5  mrg   T* get (cgraph_node *node) ATTRIBUTE_PURE
    371  1.5  mrg   {
    372  1.5  mrg     return exists (node) ? (*m_vector)[node->get_summary_id ()] : NULL;
    373  1.5  mrg   }
    374  1.4  mrg 
    375  1.5  mrg   using function_summary_base<T>::remove;
    376  1.5  mrg   void remove (cgraph_node *node)
    377  1.5  mrg   {
    378  1.5  mrg     if (exists (node))
    379  1.5  mrg       {
    380  1.5  mrg 	int id = node->get_summary_id ();
    381  1.5  mrg 	this->release ((*m_vector)[id]);
    382  1.5  mrg 	(*m_vector)[id] = NULL;
    383  1.5  mrg       }
    384  1.4  mrg   }
    385  1.4  mrg 
    386  1.5  mrg   /* Return true if a summary for the given NODE already exists.  */
    387  1.5  mrg   bool exists (cgraph_node *node)
    388  1.4  mrg   {
    389  1.5  mrg     int id = node->get_summary_id ();
    390  1.5  mrg     return (id != -1
    391  1.5  mrg 	    && (unsigned int)id < m_vector->length ()
    392  1.5  mrg 	    && (*m_vector)[id] != NULL);
    393  1.4  mrg   }
    394  1.4  mrg 
    395  1.5  mrg   /* Symbol insertion hook that is registered to symbol table.  */
    396  1.5  mrg   static void symtab_insertion (cgraph_node *node, void *data);
    397  1.5  mrg 
    398  1.5  mrg   /* Symbol removal hook that is registered to symbol table.  */
    399  1.5  mrg   static void symtab_removal (cgraph_node *node, void *data);
    400  1.5  mrg 
    401  1.5  mrg   /* Symbol duplication hook that is registered to symbol table.  */
    402  1.5  mrg   static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
    403  1.5  mrg 				  void *data);
    404  1.5  mrg 
    405  1.5  mrg private:
    406  1.5  mrg   virtual bool is_ggc ();
    407  1.5  mrg 
    408  1.5  mrg   /* Summary is stored in the vector.  */
    409  1.5  mrg   vec <T *, V> *m_vector;
    410  1.5  mrg 
    411  1.5  mrg   template <typename U> friend void gt_ggc_mx (fast_function_summary <U *, va_gc> * const &);
    412  1.5  mrg   template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &);
    413  1.5  mrg   template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &,
    414  1.5  mrg       gt_pointer_operator, void *);
    415  1.5  mrg };
    416  1.5  mrg 
    417  1.5  mrg template <typename T, typename V>
    418  1.6  mrg fast_function_summary<T *, V>::fast_function_summary (symbol_table *symtab MEM_STAT_DECL):
    419  1.6  mrg   function_summary_base<T> (symtab PASS_MEM_STAT), m_vector (NULL)
    420  1.5  mrg {
    421  1.6  mrg   vec_alloc (m_vector, 13 PASS_MEM_STAT);
    422  1.5  mrg   this->m_symtab_insertion_hook
    423  1.5  mrg     = this->m_symtab->add_cgraph_insertion_hook (fast_function_summary::symtab_insertion,
    424  1.5  mrg 						 this);
    425  1.5  mrg   this->m_symtab_removal_hook
    426  1.5  mrg     = this->m_symtab->add_cgraph_removal_hook (fast_function_summary::symtab_removal,
    427  1.5  mrg 					       this);
    428  1.5  mrg   this->m_symtab_duplication_hook
    429  1.5  mrg     = this->m_symtab->add_cgraph_duplication_hook (fast_function_summary::symtab_duplication,
    430  1.5  mrg 						   this);
    431  1.5  mrg }
    432  1.5  mrg 
    433  1.5  mrg template <typename T, typename V>
    434  1.6  mrg fast_function_summary<T *, V>::~fast_function_summary ()
    435  1.5  mrg {
    436  1.5  mrg   this->unregister_hooks ();
    437  1.5  mrg 
    438  1.5  mrg   /* Release all summaries.  */
    439  1.5  mrg   for (unsigned i = 0; i < m_vector->length (); i++)
    440  1.5  mrg     if ((*m_vector)[i] != NULL)
    441  1.5  mrg       this->release ((*m_vector)[i]);
    442  1.5  mrg   vec_free (m_vector);
    443  1.5  mrg }
    444  1.5  mrg 
    445  1.5  mrg template <typename T, typename V>
    446  1.5  mrg void
    447  1.5  mrg fast_function_summary<T *, V>::symtab_insertion (cgraph_node *node, void *data)
    448  1.5  mrg {
    449  1.5  mrg   gcc_checking_assert (node->get_uid ());
    450  1.5  mrg   fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
    451  1.5  mrg 
    452  1.5  mrg   if (summary->m_insertion_enabled)
    453  1.5  mrg     summary->insert (node, summary->get_create (node));
    454  1.5  mrg }
    455  1.5  mrg 
    456  1.5  mrg template <typename T, typename V>
    457  1.5  mrg void
    458  1.5  mrg fast_function_summary<T *, V>::symtab_removal (cgraph_node *node, void *data)
    459  1.5  mrg {
    460  1.5  mrg   gcc_checking_assert (node->get_uid ());
    461  1.5  mrg   fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
    462  1.5  mrg 
    463  1.5  mrg   if (summary->exists (node))
    464  1.5  mrg     summary->remove (node);
    465  1.5  mrg }
    466  1.5  mrg 
    467  1.5  mrg template <typename T, typename V>
    468  1.5  mrg void
    469  1.5  mrg fast_function_summary<T *, V>::symtab_duplication (cgraph_node *node,
    470  1.5  mrg 						   cgraph_node *node2,
    471  1.5  mrg 						   void *data)
    472  1.5  mrg {
    473  1.5  mrg   fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
    474  1.5  mrg   T *v = summary->get (node);
    475  1.5  mrg 
    476  1.5  mrg   if (v)
    477  1.5  mrg     {
    478  1.5  mrg       T *duplicate = summary->get_create (node2);
    479  1.5  mrg       summary->duplicate (node, node2, v, duplicate);
    480  1.5  mrg     }
    481  1.5  mrg }
    482  1.5  mrg 
    483  1.5  mrg template <typename T, typename V>
    484  1.5  mrg inline bool
    485  1.5  mrg fast_function_summary<T *, V>::is_ggc ()
    486  1.5  mrg {
    487  1.5  mrg   return is_same<V, va_gc>::value;
    488  1.5  mrg }
    489  1.5  mrg 
    490  1.5  mrg template <typename T>
    491  1.5  mrg void
    492  1.5  mrg gt_ggc_mx (fast_function_summary<T *, va_heap>* const &)
    493  1.5  mrg {
    494  1.5  mrg }
    495  1.5  mrg 
    496  1.5  mrg template <typename T>
    497  1.5  mrg void
    498  1.5  mrg gt_pch_nx (fast_function_summary<T *, va_heap>* const &)
    499  1.5  mrg {
    500  1.5  mrg }
    501  1.5  mrg 
    502  1.5  mrg template <typename T>
    503  1.5  mrg void
    504  1.5  mrg gt_pch_nx (fast_function_summary<T *, va_heap>* const&, gt_pointer_operator,
    505  1.5  mrg 	   void *)
    506  1.5  mrg {
    507  1.5  mrg }
    508  1.5  mrg 
    509  1.5  mrg template <typename T>
    510  1.5  mrg void
    511  1.5  mrg gt_ggc_mx (fast_function_summary<T *, va_gc>* const &summary)
    512  1.5  mrg {
    513  1.5  mrg   ggc_test_and_set_mark (summary->m_vector);
    514  1.5  mrg   gt_ggc_mx (summary->m_vector);
    515  1.5  mrg }
    516  1.5  mrg 
    517  1.5  mrg template <typename T>
    518  1.5  mrg void
    519  1.6  mrg gt_pch_nx (fast_function_summary<T *, va_gc> *const &)
    520  1.5  mrg {
    521  1.6  mrg   gcc_unreachable ();
    522  1.5  mrg }
    523  1.5  mrg 
    524  1.5  mrg template <typename T>
    525  1.5  mrg void
    526  1.6  mrg gt_pch_nx (fast_function_summary<T *, va_gc> *const &, gt_pointer_operator,
    527  1.6  mrg 	   void *)
    528  1.5  mrg {
    529  1.6  mrg   gcc_unreachable ();
    530  1.5  mrg }
    531  1.5  mrg 
    532  1.5  mrg /* Base class for call_summary and fast_call_summary classes.  */
    533  1.5  mrg 
    534  1.5  mrg template <class T>
    535  1.5  mrg class call_summary_base
    536  1.5  mrg {
    537  1.5  mrg public:
    538  1.5  mrg   /* Default construction takes SYMTAB as an argument.  */
    539  1.6  mrg   call_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO):
    540  1.6  mrg   m_symtab (symtab),
    541  1.6  mrg   m_initialize_when_cloning (false),
    542  1.6  mrg   m_allocator ("call summary" PASS_MEM_STAT)
    543  1.5  mrg   {}
    544  1.5  mrg 
    545  1.4  mrg   /* Basic implementation of removal operation.  */
    546  1.4  mrg   virtual void remove (cgraph_edge *, T *) {}
    547  1.4  mrg 
    548  1.4  mrg   /* Basic implementation of duplication operation.  */
    549  1.4  mrg   virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *) {}
    550  1.4  mrg 
    551  1.5  mrg protected:
    552  1.4  mrg   /* Allocates new data that are stored within map.  */
    553  1.4  mrg   T* allocate_new ()
    554  1.4  mrg   {
    555  1.4  mrg     /* Call gcc_internal_because we do not want to call finalizer for
    556  1.4  mrg        a type T.  We call dtor explicitly.  */
    557  1.6  mrg     return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
    558  1.6  mrg 		     : m_allocator.allocate ();
    559  1.4  mrg   }
    560  1.4  mrg 
    561  1.4  mrg   /* Release an item that is stored within map.  */
    562  1.4  mrg   void release (T *item)
    563  1.4  mrg   {
    564  1.5  mrg     if (is_ggc ())
    565  1.6  mrg       ggc_delete (item);
    566  1.4  mrg     else
    567  1.6  mrg       m_allocator.remove (item);
    568  1.4  mrg   }
    569  1.4  mrg 
    570  1.5  mrg   /* Unregister all call-graph hooks.  */
    571  1.5  mrg   void unregister_hooks ();
    572  1.5  mrg 
    573  1.5  mrg   /* Symbol table the summary is registered to.  */
    574  1.5  mrg   symbol_table *m_symtab;
    575  1.5  mrg 
    576  1.5  mrg   /* Internal summary removal hook pointer.  */
    577  1.5  mrg   cgraph_edge_hook_list *m_symtab_removal_hook;
    578  1.5  mrg   /* Internal summary duplication hook pointer.  */
    579  1.5  mrg   cgraph_2edge_hook_list *m_symtab_duplication_hook;
    580  1.5  mrg   /* Initialize summary for an edge that is cloned.  */
    581  1.5  mrg   bool m_initialize_when_cloning;
    582  1.5  mrg 
    583  1.5  mrg private:
    584  1.5  mrg   /* Return true when the summary uses GGC memory for allocation.  */
    585  1.5  mrg   virtual bool is_ggc () = 0;
    586  1.6  mrg 
    587  1.6  mrg   /* Object allocator for heap allocation.  */
    588  1.6  mrg   object_allocator<T> m_allocator;
    589  1.5  mrg };
    590  1.5  mrg 
    591  1.5  mrg template <typename T>
    592  1.5  mrg void
    593  1.5  mrg call_summary_base<T>::unregister_hooks ()
    594  1.5  mrg {
    595  1.5  mrg   m_symtab->remove_edge_removal_hook (m_symtab_removal_hook);
    596  1.5  mrg   m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook);
    597  1.5  mrg }
    598  1.5  mrg 
    599  1.5  mrg /* An impossible class templated by non-pointers so, which makes sure that only
    600  1.5  mrg    summaries gathering pointers can be created.  */
    601  1.5  mrg 
    602  1.5  mrg template <class T>
    603  1.5  mrg class call_summary
    604  1.5  mrg {
    605  1.5  mrg private:
    606  1.5  mrg   call_summary ();
    607  1.5  mrg };
    608  1.5  mrg 
    609  1.5  mrg /* Class to store auxiliary information about call graph edges.  */
    610  1.5  mrg 
    611  1.5  mrg template <class T>
    612  1.5  mrg class GTY((user)) call_summary <T *>: public call_summary_base<T>
    613  1.5  mrg {
    614  1.5  mrg public:
    615  1.5  mrg   /* Default construction takes SYMTAB as an argument.  */
    616  1.6  mrg   call_summary (symbol_table *symtab, bool ggc = false
    617  1.6  mrg 		CXX_MEM_STAT_INFO)
    618  1.6  mrg   : call_summary_base<T> (symtab PASS_MEM_STAT), m_ggc (ggc),
    619  1.6  mrg     m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT)
    620  1.4  mrg   {
    621  1.5  mrg     this->m_symtab_removal_hook
    622  1.5  mrg       = this->m_symtab->add_edge_removal_hook (call_summary::symtab_removal,
    623  1.5  mrg 					       this);
    624  1.5  mrg     this->m_symtab_duplication_hook
    625  1.5  mrg       = this->m_symtab->add_edge_duplication_hook (call_summary::symtab_duplication,
    626  1.5  mrg 						   this);
    627  1.4  mrg   }
    628  1.4  mrg 
    629  1.5  mrg   /* Destructor.  */
    630  1.6  mrg   virtual ~call_summary ();
    631  1.5  mrg 
    632  1.5  mrg   /* Traverses all summarys with an edge E called with
    633  1.5  mrg      ARG as argument.  */
    634  1.5  mrg   template<typename Arg, bool (*f)(const T &, Arg)>
    635  1.5  mrg   void traverse (Arg a) const
    636  1.4  mrg   {
    637  1.7  mrg     m_map.template traverse <f> (a);
    638  1.4  mrg   }
    639  1.4  mrg 
    640  1.5  mrg   /* Getter for summary callgraph edge pointer.
    641  1.5  mrg      If a summary for an edge does not exist, it will be created.  */
    642  1.5  mrg   T* get_create (cgraph_edge *edge)
    643  1.4  mrg   {
    644  1.5  mrg     bool existed;
    645  1.5  mrg     T **v = &m_map.get_or_insert (edge->get_uid (), &existed);
    646  1.5  mrg     if (!existed)
    647  1.5  mrg       *v = this->allocate_new ();
    648  1.5  mrg 
    649  1.5  mrg     return *v;
    650  1.5  mrg   }
    651  1.4  mrg 
    652  1.5  mrg   /* Getter for summary callgraph edge pointer.  */
    653  1.5  mrg   T* get (cgraph_edge *edge) ATTRIBUTE_PURE
    654  1.5  mrg   {
    655  1.5  mrg     T **v = m_map.get (edge->get_uid ());
    656  1.5  mrg     return v == NULL ? NULL : *v;
    657  1.5  mrg   }
    658  1.4  mrg 
    659  1.5  mrg   /* Remove edge from summary.  */
    660  1.5  mrg   using call_summary_base<T>::remove;
    661  1.5  mrg   void remove (cgraph_edge *edge)
    662  1.5  mrg   {
    663  1.5  mrg     int uid = edge->get_uid ();
    664  1.5  mrg     T **v = m_map.get (uid);
    665  1.4  mrg     if (v)
    666  1.4  mrg       {
    667  1.5  mrg 	m_map.remove (uid);
    668  1.5  mrg 	this->release (*v);
    669  1.4  mrg       }
    670  1.4  mrg   }
    671  1.4  mrg 
    672  1.5  mrg   /* Return true if a summary for the given EDGE already exists.  */
    673  1.5  mrg   bool exists (cgraph_edge *edge)
    674  1.5  mrg   {
    675  1.5  mrg     return m_map.get (edge->get_uid ()) != NULL;
    676  1.5  mrg   }
    677  1.5  mrg 
    678  1.5  mrg   /* Symbol removal hook that is registered to symbol table.  */
    679  1.5  mrg   static void symtab_removal (cgraph_edge *edge, void *data);
    680  1.5  mrg 
    681  1.4  mrg   /* Symbol duplication hook that is registered to symbol table.  */
    682  1.4  mrg   static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
    683  1.5  mrg 				  void *data);
    684  1.4  mrg 
    685  1.4  mrg protected:
    686  1.4  mrg   /* Indication if we use ggc summary.  */
    687  1.4  mrg   bool m_ggc;
    688  1.4  mrg 
    689  1.4  mrg private:
    690  1.5  mrg   /* Indication if we use ggc summary.  */
    691  1.5  mrg   virtual bool is_ggc ()
    692  1.4  mrg   {
    693  1.5  mrg     return m_ggc;
    694  1.4  mrg   }
    695  1.4  mrg 
    696  1.5  mrg   typedef int_hash <int, 0, -1> map_hash;
    697  1.4  mrg 
    698  1.4  mrg   /* Main summary store, where summary ID is used as key.  */
    699  1.4  mrg   hash_map <map_hash, T *> m_map;
    700  1.4  mrg 
    701  1.4  mrg   template <typename U> friend void gt_ggc_mx (call_summary <U *> * const &);
    702  1.4  mrg   template <typename U> friend void gt_pch_nx (call_summary <U *> * const &);
    703  1.4  mrg   template <typename U> friend void gt_pch_nx (call_summary <U *> * const &,
    704  1.4  mrg       gt_pointer_operator, void *);
    705  1.4  mrg };
    706  1.4  mrg 
    707  1.4  mrg template <typename T>
    708  1.6  mrg call_summary<T *>::~call_summary ()
    709  1.5  mrg {
    710  1.5  mrg   this->unregister_hooks ();
    711  1.5  mrg 
    712  1.5  mrg   /* Release all summaries.  */
    713  1.5  mrg   typedef typename hash_map <map_hash, T *>::iterator map_iterator;
    714  1.5  mrg   for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
    715  1.5  mrg     this->release ((*it).second);
    716  1.5  mrg }
    717  1.5  mrg 
    718  1.5  mrg template <typename T>
    719  1.5  mrg void
    720  1.5  mrg call_summary<T *>::symtab_removal (cgraph_edge *edge, void *data)
    721  1.5  mrg {
    722  1.5  mrg   call_summary *summary = (call_summary <T *> *) (data);
    723  1.5  mrg   summary->remove (edge);
    724  1.5  mrg }
    725  1.5  mrg 
    726  1.5  mrg template <typename T>
    727  1.5  mrg void
    728  1.5  mrg call_summary<T *>::symtab_duplication (cgraph_edge *edge1,
    729  1.5  mrg 				       cgraph_edge *edge2, void *data)
    730  1.5  mrg {
    731  1.5  mrg   call_summary *summary = (call_summary <T *> *) (data);
    732  1.5  mrg   T *edge1_summary = NULL;
    733  1.5  mrg 
    734  1.5  mrg   if (summary->m_initialize_when_cloning)
    735  1.5  mrg     edge1_summary = summary->get_create (edge1);
    736  1.5  mrg   else
    737  1.5  mrg     edge1_summary = summary->get (edge1);
    738  1.5  mrg 
    739  1.5  mrg   if (edge1_summary)
    740  1.5  mrg     summary->duplicate (edge1, edge2, edge1_summary,
    741  1.5  mrg 			summary->get_create (edge2));
    742  1.5  mrg }
    743  1.5  mrg 
    744  1.5  mrg template <typename T>
    745  1.5  mrg void
    746  1.4  mrg gt_ggc_mx(call_summary<T *>* const &summary)
    747  1.4  mrg {
    748  1.4  mrg   gcc_checking_assert (summary->m_ggc);
    749  1.4  mrg   gt_ggc_mx (&summary->m_map);
    750  1.4  mrg }
    751  1.4  mrg 
    752  1.4  mrg template <typename T>
    753  1.4  mrg void
    754  1.6  mrg gt_pch_nx (call_summary<T *> *const &)
    755  1.4  mrg {
    756  1.6  mrg   gcc_unreachable ();
    757  1.4  mrg }
    758  1.4  mrg 
    759  1.4  mrg template <typename T>
    760  1.4  mrg void
    761  1.6  mrg gt_pch_nx (call_summary<T *> *const &, gt_pointer_operator, void *)
    762  1.4  mrg {
    763  1.6  mrg   gcc_unreachable ();
    764  1.4  mrg }
    765  1.4  mrg 
    766  1.5  mrg /* We want to pass just pointer types as argument for fast_call_summary
    767  1.5  mrg    template class.  */
    768  1.5  mrg 
    769  1.5  mrg template <class T, class V>
    770  1.5  mrg class fast_call_summary
    771  1.5  mrg {
    772  1.5  mrg private:
    773  1.5  mrg   fast_call_summary ();
    774  1.5  mrg };
    775  1.5  mrg 
    776  1.5  mrg /* Call vector summary is a fast implementation of call_summary that
    777  1.5  mrg    utilizes vector as primary storage of summaries.  */
    778  1.5  mrg 
    779  1.5  mrg template <class T, class V>
    780  1.5  mrg class GTY((user)) fast_call_summary <T *, V>: public call_summary_base<T>
    781  1.5  mrg {
    782  1.5  mrg public:
    783  1.5  mrg   /* Default construction takes SYMTAB as an argument.  */
    784  1.6  mrg   fast_call_summary (symbol_table *symtab CXX_MEM_STAT_INFO)
    785  1.6  mrg   : call_summary_base<T> (symtab PASS_MEM_STAT), m_vector (NULL)
    786  1.5  mrg   {
    787  1.6  mrg     vec_alloc (m_vector, 13 PASS_MEM_STAT);
    788  1.5  mrg     this->m_symtab_removal_hook
    789  1.5  mrg       = this->m_symtab->add_edge_removal_hook (fast_call_summary::symtab_removal,
    790  1.5  mrg 					       this);
    791  1.5  mrg     this->m_symtab_duplication_hook
    792  1.5  mrg       = this->m_symtab->add_edge_duplication_hook (fast_call_summary::symtab_duplication,
    793  1.5  mrg 						   this);
    794  1.5  mrg   }
    795  1.5  mrg 
    796  1.5  mrg   /* Destructor.  */
    797  1.6  mrg   virtual ~fast_call_summary ();
    798  1.5  mrg 
    799  1.5  mrg   /* Traverses all summarys with an edge F called with
    800  1.5  mrg      ARG as argument.  */
    801  1.5  mrg   template<typename Arg, bool (*f)(const T &, Arg)>
    802  1.5  mrg   void traverse (Arg a) const
    803  1.5  mrg   {
    804  1.5  mrg     for (unsigned i = 0; i < m_vector->length (); i++)
    805  1.5  mrg       if ((*m_vector[i]) != NULL)
    806  1.6  mrg 	f ((*m_vector)[i], a);
    807  1.5  mrg   }
    808  1.5  mrg 
    809  1.5  mrg   /* Getter for summary callgraph edge pointer.
    810  1.5  mrg      If a summary for an edge does not exist, it will be created.  */
    811  1.5  mrg   T* get_create (cgraph_edge *edge)
    812  1.5  mrg   {
    813  1.5  mrg     int id = edge->get_summary_id ();
    814  1.5  mrg     if (id == -1)
    815  1.5  mrg       id = this->m_symtab->assign_summary_id (edge);
    816  1.5  mrg 
    817  1.5  mrg     if ((unsigned)id >= m_vector->length ())
    818  1.6  mrg       {
    819  1.6  mrg 	int newlen = this->m_symtab->edges_max_summary_id;
    820  1.6  mrg 	m_vector->reserve (newlen - m_vector->length ());
    821  1.6  mrg 	m_vector->quick_grow_cleared (newlen);
    822  1.6  mrg       }
    823  1.5  mrg 
    824  1.5  mrg     if ((*m_vector)[id] == NULL)
    825  1.5  mrg       (*m_vector)[id] = this->allocate_new ();
    826  1.5  mrg 
    827  1.5  mrg     return (*m_vector)[id];
    828  1.5  mrg   }
    829  1.5  mrg 
    830  1.5  mrg   /* Getter for summary callgraph edge pointer.  */
    831  1.5  mrg   T* get (cgraph_edge *edge) ATTRIBUTE_PURE
    832  1.5  mrg   {
    833  1.5  mrg     return exists (edge) ? (*m_vector)[edge->get_summary_id ()] : NULL;
    834  1.5  mrg   }
    835  1.5  mrg 
    836  1.5  mrg   /* Remove edge from summary.  */
    837  1.5  mrg   using call_summary_base<T>::remove;
    838  1.5  mrg   void remove (cgraph_edge *edge)
    839  1.5  mrg   {
    840  1.5  mrg     if (exists (edge))
    841  1.5  mrg       {
    842  1.5  mrg 	int id = edge->get_summary_id ();
    843  1.5  mrg 	this->release ((*m_vector)[id]);
    844  1.5  mrg 	(*m_vector)[id] = NULL;
    845  1.5  mrg       }
    846  1.5  mrg   }
    847  1.5  mrg 
    848  1.5  mrg   /* Return true if a summary for the given EDGE already exists.  */
    849  1.5  mrg   bool exists (cgraph_edge *edge)
    850  1.5  mrg   {
    851  1.5  mrg     int id = edge->get_summary_id ();
    852  1.5  mrg     return (id != -1
    853  1.5  mrg 	    && (unsigned)id < m_vector->length ()
    854  1.5  mrg 	    && (*m_vector)[id] != NULL);
    855  1.5  mrg   }
    856  1.5  mrg 
    857  1.5  mrg   /* Symbol removal hook that is registered to symbol table.  */
    858  1.5  mrg   static void symtab_removal (cgraph_edge *edge, void *data);
    859  1.5  mrg 
    860  1.5  mrg   /* Symbol duplication hook that is registered to symbol table.  */
    861  1.5  mrg   static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
    862  1.5  mrg 				  void *data);
    863  1.5  mrg 
    864  1.5  mrg private:
    865  1.5  mrg   virtual bool is_ggc ();
    866  1.5  mrg 
    867  1.5  mrg   /* Summary is stored in the vector.  */
    868  1.5  mrg   vec <T *, V> *m_vector;
    869  1.5  mrg 
    870  1.5  mrg   template <typename U> friend void gt_ggc_mx (fast_call_summary <U *, va_gc> * const &);
    871  1.5  mrg   template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &);
    872  1.5  mrg   template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &,
    873  1.5  mrg       gt_pointer_operator, void *);
    874  1.5  mrg };
    875  1.5  mrg 
    876  1.5  mrg template <typename T, typename V>
    877  1.6  mrg fast_call_summary<T *, V>::~fast_call_summary ()
    878  1.5  mrg {
    879  1.5  mrg   this->unregister_hooks ();
    880  1.5  mrg 
    881  1.5  mrg   /* Release all summaries.  */
    882  1.5  mrg   for (unsigned i = 0; i < m_vector->length (); i++)
    883  1.5  mrg     if ((*m_vector)[i] != NULL)
    884  1.5  mrg       this->release ((*m_vector)[i]);
    885  1.5  mrg   vec_free (m_vector);
    886  1.5  mrg }
    887  1.5  mrg 
    888  1.5  mrg template <typename T, typename V>
    889  1.5  mrg void
    890  1.5  mrg fast_call_summary<T *, V>::symtab_removal (cgraph_edge *edge, void *data)
    891  1.5  mrg {
    892  1.5  mrg   fast_call_summary *summary = (fast_call_summary <T *, V> *) (data);
    893  1.5  mrg   summary->remove (edge);
    894  1.5  mrg }
    895  1.5  mrg 
    896  1.5  mrg template <typename T, typename V>
    897  1.5  mrg void
    898  1.5  mrg fast_call_summary<T *, V>::symtab_duplication (cgraph_edge *edge1,
    899  1.5  mrg 						 cgraph_edge *edge2, void *data)
    900  1.5  mrg {
    901  1.5  mrg   fast_call_summary *summary = (fast_call_summary <T *, V> *) (data);
    902  1.5  mrg   T *edge1_summary = NULL;
    903  1.5  mrg 
    904  1.5  mrg   if (summary->m_initialize_when_cloning)
    905  1.5  mrg     edge1_summary = summary->get_create (edge1);
    906  1.5  mrg   else
    907  1.5  mrg     edge1_summary = summary->get (edge1);
    908  1.5  mrg 
    909  1.5  mrg   if (edge1_summary)
    910  1.5  mrg     {
    911  1.5  mrg       T *duplicate = summary->get_create (edge2);
    912  1.5  mrg       summary->duplicate (edge1, edge2, edge1_summary, duplicate);
    913  1.5  mrg     }
    914  1.5  mrg }
    915  1.5  mrg 
    916  1.5  mrg template <typename T, typename V>
    917  1.5  mrg inline bool
    918  1.5  mrg fast_call_summary<T *, V>::is_ggc ()
    919  1.5  mrg {
    920  1.5  mrg   return is_same<V, va_gc>::value;
    921  1.5  mrg }
    922  1.5  mrg 
    923  1.5  mrg template <typename T>
    924  1.5  mrg void
    925  1.6  mrg gt_ggc_mx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED)
    926  1.5  mrg {
    927  1.5  mrg }
    928  1.5  mrg 
    929  1.5  mrg template <typename T>
    930  1.5  mrg void
    931  1.6  mrg gt_pch_nx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED)
    932  1.5  mrg {
    933  1.5  mrg }
    934  1.5  mrg 
    935  1.5  mrg template <typename T>
    936  1.5  mrg void
    937  1.6  mrg gt_pch_nx (fast_call_summary<T *, va_heap>* const& summary ATTRIBUTE_UNUSED,
    938  1.6  mrg 	   gt_pointer_operator op ATTRIBUTE_UNUSED,
    939  1.6  mrg 	   void *cookie ATTRIBUTE_UNUSED)
    940  1.5  mrg {
    941  1.5  mrg }
    942  1.5  mrg 
    943  1.5  mrg template <typename T>
    944  1.5  mrg void
    945  1.5  mrg gt_ggc_mx (fast_call_summary<T *, va_gc>* const &summary)
    946  1.5  mrg {
    947  1.5  mrg   ggc_test_and_set_mark (summary->m_vector);
    948  1.5  mrg   gt_ggc_mx (&summary->m_vector);
    949  1.5  mrg }
    950  1.5  mrg 
    951  1.5  mrg template <typename T>
    952  1.5  mrg void
    953  1.6  mrg gt_pch_nx (fast_call_summary<T *, va_gc> *const &)
    954  1.5  mrg {
    955  1.6  mrg   gcc_unreachable ();
    956  1.5  mrg }
    957  1.5  mrg 
    958  1.5  mrg template <typename T>
    959  1.5  mrg void
    960  1.6  mrg gt_pch_nx (fast_call_summary<T *, va_gc> *const &, gt_pointer_operator, void *)
    961  1.5  mrg {
    962  1.6  mrg   gcc_unreachable ();
    963  1.5  mrg }
    964  1.5  mrg 
    965  1.1  mrg #endif  /* GCC_SYMBOL_SUMMARY_H  */
    966