Home | History | Annotate | Line # | Download | only in gcc
symbol-summary.h revision 1.3
      1  1.1  mrg /* Callgraph summary data structure.
      2  1.3  mrg    Copyright (C) 2014-2017 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.1  mrg /* We want to pass just pointer types as argument for function_summary
     25  1.1  mrg    template class.  */
     26  1.1  mrg 
     27  1.1  mrg template <class T>
     28  1.1  mrg class function_summary
     29  1.1  mrg {
     30  1.1  mrg private:
     31  1.1  mrg   function_summary();
     32  1.1  mrg };
     33  1.1  mrg 
     34  1.1  mrg template <class T>
     35  1.1  mrg class GTY((user)) function_summary <T *>
     36  1.1  mrg {
     37  1.1  mrg public:
     38  1.1  mrg   /* Default construction takes SYMTAB as an argument.  */
     39  1.1  mrg   function_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
     40  1.3  mrg     m_insertion_enabled (true), m_released (false), m_map (13, ggc),
     41  1.3  mrg     m_symtab (symtab)
     42  1.1  mrg   {
     43  1.1  mrg     m_symtab_insertion_hook =
     44  1.1  mrg       symtab->add_cgraph_insertion_hook
     45  1.1  mrg       (function_summary::symtab_insertion, this);
     46  1.1  mrg 
     47  1.1  mrg     m_symtab_removal_hook =
     48  1.1  mrg       symtab->add_cgraph_removal_hook
     49  1.1  mrg       (function_summary::symtab_removal, this);
     50  1.1  mrg     m_symtab_duplication_hook =
     51  1.1  mrg       symtab->add_cgraph_duplication_hook
     52  1.1  mrg       (function_summary::symtab_duplication, this);
     53  1.1  mrg   }
     54  1.1  mrg 
     55  1.1  mrg   /* Destructor.  */
     56  1.1  mrg   virtual ~function_summary ()
     57  1.1  mrg   {
     58  1.1  mrg     release ();
     59  1.1  mrg   }
     60  1.1  mrg 
     61  1.1  mrg   /* Destruction method that can be called for GGT purpose.  */
     62  1.1  mrg   void release ()
     63  1.1  mrg   {
     64  1.3  mrg     if (m_released)
     65  1.3  mrg       return;
     66  1.1  mrg 
     67  1.3  mrg     m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
     68  1.3  mrg     m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
     69  1.3  mrg     m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
     70  1.1  mrg 
     71  1.1  mrg     /* Release all summaries.  */
     72  1.3  mrg     typedef typename hash_map <map_hash, T *>::iterator map_iterator;
     73  1.1  mrg     for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
     74  1.1  mrg       release ((*it).second);
     75  1.3  mrg 
     76  1.3  mrg     m_released = true;
     77  1.1  mrg   }
     78  1.1  mrg 
     79  1.1  mrg   /* Traverses all summarys with a function F called with
     80  1.1  mrg      ARG as argument.  */
     81  1.1  mrg   template<typename Arg, bool (*f)(const T &, Arg)>
     82  1.1  mrg   void traverse (Arg a) const
     83  1.1  mrg   {
     84  1.1  mrg     m_map.traverse <f> (a);
     85  1.1  mrg   }
     86  1.1  mrg 
     87  1.1  mrg   /* Basic implementation of insert operation.  */
     88  1.1  mrg   virtual void insert (cgraph_node *, T *) {}
     89  1.1  mrg 
     90  1.1  mrg   /* Basic implementation of removal operation.  */
     91  1.1  mrg   virtual void remove (cgraph_node *, T *) {}
     92  1.1  mrg 
     93  1.1  mrg   /* Basic implementation of duplication operation.  */
     94  1.1  mrg   virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {}
     95  1.1  mrg 
     96  1.1  mrg   /* Allocates new data that are stored within map.  */
     97  1.1  mrg   T* allocate_new ()
     98  1.1  mrg   {
     99  1.3  mrg     /* Call gcc_internal_because we do not want to call finalizer for
    100  1.3  mrg        a type T.  We call dtor explicitly.  */
    101  1.3  mrg     return m_ggc ? new (ggc_internal_alloc (sizeof (T))) T () : new T () ;
    102  1.1  mrg   }
    103  1.1  mrg 
    104  1.1  mrg   /* Release an item that is stored within map.  */
    105  1.1  mrg   void release (T *item)
    106  1.1  mrg   {
    107  1.1  mrg     if (m_ggc)
    108  1.1  mrg       {
    109  1.1  mrg 	item->~T ();
    110  1.1  mrg 	ggc_free (item);
    111  1.1  mrg       }
    112  1.1  mrg     else
    113  1.1  mrg       delete item;
    114  1.1  mrg   }
    115  1.1  mrg 
    116  1.1  mrg   /* Getter for summary callgraph node pointer.  */
    117  1.1  mrg   T* get (cgraph_node *node)
    118  1.1  mrg   {
    119  1.3  mrg     gcc_checking_assert (node->summary_uid);
    120  1.1  mrg     return get (node->summary_uid);
    121  1.1  mrg   }
    122  1.1  mrg 
    123  1.1  mrg   /* Return number of elements handled by data structure.  */
    124  1.1  mrg   size_t elements ()
    125  1.1  mrg   {
    126  1.1  mrg     return m_map.elements ();
    127  1.1  mrg   }
    128  1.1  mrg 
    129  1.1  mrg   /* Enable insertion hook invocation.  */
    130  1.1  mrg   void enable_insertion_hook ()
    131  1.1  mrg   {
    132  1.1  mrg     m_insertion_enabled = true;
    133  1.1  mrg   }
    134  1.1  mrg 
    135  1.1  mrg   /* Enable insertion hook invocation.  */
    136  1.1  mrg   void disable_insertion_hook ()
    137  1.1  mrg   {
    138  1.1  mrg     m_insertion_enabled = false;
    139  1.1  mrg   }
    140  1.1  mrg 
    141  1.1  mrg   /* Symbol insertion hook that is registered to symbol table.  */
    142  1.1  mrg   static void symtab_insertion (cgraph_node *node, void *data)
    143  1.1  mrg   {
    144  1.3  mrg     gcc_checking_assert (node->summary_uid);
    145  1.1  mrg     function_summary *summary = (function_summary <T *> *) (data);
    146  1.1  mrg 
    147  1.1  mrg     if (summary->m_insertion_enabled)
    148  1.1  mrg       summary->insert (node, summary->get (node));
    149  1.1  mrg   }
    150  1.1  mrg 
    151  1.1  mrg   /* Symbol removal hook that is registered to symbol table.  */
    152  1.1  mrg   static void symtab_removal (cgraph_node *node, void *data)
    153  1.1  mrg   {
    154  1.1  mrg     gcc_checking_assert (node->summary_uid);
    155  1.1  mrg     function_summary *summary = (function_summary <T *> *) (data);
    156  1.1  mrg 
    157  1.1  mrg     int summary_uid = node->summary_uid;
    158  1.1  mrg     T **v = summary->m_map.get (summary_uid);
    159  1.1  mrg 
    160  1.1  mrg     if (v)
    161  1.1  mrg       {
    162  1.1  mrg 	summary->remove (node, *v);
    163  1.1  mrg 
    164  1.1  mrg 	if (!summary->m_ggc)
    165  1.1  mrg 	  delete (*v);
    166  1.1  mrg 
    167  1.1  mrg 	summary->m_map.remove (summary_uid);
    168  1.1  mrg       }
    169  1.1  mrg   }
    170  1.1  mrg 
    171  1.1  mrg   /* Symbol duplication hook that is registered to symbol table.  */
    172  1.1  mrg   static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
    173  1.1  mrg 				  void *data)
    174  1.1  mrg   {
    175  1.1  mrg     function_summary *summary = (function_summary <T *> *) (data);
    176  1.1  mrg     T **v = summary->m_map.get (node->summary_uid);
    177  1.1  mrg 
    178  1.1  mrg     gcc_checking_assert (node2->summary_uid > 0);
    179  1.1  mrg 
    180  1.1  mrg     if (v)
    181  1.1  mrg       {
    182  1.1  mrg 	/* This load is necessary, because we insert a new value!  */
    183  1.1  mrg 	T *data = *v;
    184  1.1  mrg 	T *duplicate = summary->allocate_new ();
    185  1.1  mrg 	summary->m_map.put (node2->summary_uid, duplicate);
    186  1.1  mrg 	summary->duplicate (node, node2, data, duplicate);
    187  1.1  mrg       }
    188  1.1  mrg   }
    189  1.1  mrg 
    190  1.1  mrg protected:
    191  1.1  mrg   /* Indication if we use ggc summary.  */
    192  1.1  mrg   bool m_ggc;
    193  1.1  mrg 
    194  1.1  mrg private:
    195  1.3  mrg   typedef int_hash <int, 0, -1> map_hash;
    196  1.1  mrg 
    197  1.1  mrg   /* Getter for summary callgraph ID.  */
    198  1.1  mrg   T* get (int uid)
    199  1.1  mrg   {
    200  1.1  mrg     bool existed;
    201  1.1  mrg     T **v = &m_map.get_or_insert (uid, &existed);
    202  1.1  mrg     if (!existed)
    203  1.1  mrg       *v = allocate_new ();
    204  1.1  mrg 
    205  1.1  mrg     return *v;
    206  1.1  mrg   }
    207  1.1  mrg 
    208  1.3  mrg   /* Indicates if insertion hook is enabled.  */
    209  1.3  mrg   bool m_insertion_enabled;
    210  1.3  mrg   /* Indicates if the summary is released.  */
    211  1.3  mrg   bool m_released;
    212  1.1  mrg   /* Main summary store, where summary ID is used as key.  */
    213  1.3  mrg   hash_map <map_hash, T *> m_map;
    214  1.1  mrg   /* Internal summary insertion hook pointer.  */
    215  1.1  mrg   cgraph_node_hook_list *m_symtab_insertion_hook;
    216  1.1  mrg   /* Internal summary removal hook pointer.  */
    217  1.1  mrg   cgraph_node_hook_list *m_symtab_removal_hook;
    218  1.1  mrg   /* Internal summary duplication hook pointer.  */
    219  1.1  mrg   cgraph_2node_hook_list *m_symtab_duplication_hook;
    220  1.1  mrg   /* Symbol table the summary is registered to.  */
    221  1.1  mrg   symbol_table *m_symtab;
    222  1.1  mrg 
    223  1.1  mrg   template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &);
    224  1.1  mrg   template <typename U> friend void gt_pch_nx (function_summary <U *> * const &);
    225  1.1  mrg   template <typename U> friend void gt_pch_nx (function_summary <U *> * const &,
    226  1.1  mrg       gt_pointer_operator, void *);
    227  1.1  mrg };
    228  1.1  mrg 
    229  1.1  mrg template <typename T>
    230  1.1  mrg void
    231  1.1  mrg gt_ggc_mx(function_summary<T *>* const &summary)
    232  1.1  mrg {
    233  1.1  mrg   gcc_checking_assert (summary->m_ggc);
    234  1.1  mrg   gt_ggc_mx (&summary->m_map);
    235  1.1  mrg }
    236  1.1  mrg 
    237  1.1  mrg template <typename T>
    238  1.1  mrg void
    239  1.1  mrg gt_pch_nx(function_summary<T *>* const &summary)
    240  1.1  mrg {
    241  1.1  mrg   gcc_checking_assert (summary->m_ggc);
    242  1.1  mrg   gt_pch_nx (&summary->m_map);
    243  1.1  mrg }
    244  1.1  mrg 
    245  1.1  mrg template <typename T>
    246  1.1  mrg void
    247  1.1  mrg gt_pch_nx(function_summary<T *>* const& summary, gt_pointer_operator op,
    248  1.1  mrg 	  void *cookie)
    249  1.1  mrg {
    250  1.1  mrg   gcc_checking_assert (summary->m_ggc);
    251  1.1  mrg   gt_pch_nx (&summary->m_map, op, cookie);
    252  1.1  mrg }
    253  1.1  mrg 
    254  1.1  mrg #endif  /* GCC_SYMBOL_SUMMARY_H  */
    255