123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- /* Callgraph summary data structure.
- Copyright (C) 2014-2015 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
- /* We want to pass just pointer types as argument for function_summary
- template class. */
- template <class T>
- class function_summary
- {
- private:
- function_summary();
- };
- template <class T>
- class GTY((user)) function_summary <T *>
- {
- public:
- /* Default construction takes SYMTAB as an argument. */
- function_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
- m_map (13, ggc), m_insertion_enabled (true), m_symtab (symtab)
- {
- #ifdef ENABLE_CHECKING
- cgraph_node *node;
- FOR_EACH_FUNCTION (node)
- {
- gcc_checking_assert (node->summary_uid > 0);
- }
- #endif
- m_symtab_insertion_hook =
- symtab->add_cgraph_insertion_hook
- (function_summary::symtab_insertion, this);
- m_symtab_removal_hook =
- symtab->add_cgraph_removal_hook
- (function_summary::symtab_removal, this);
- m_symtab_duplication_hook =
- symtab->add_cgraph_duplication_hook
- (function_summary::symtab_duplication, this);
- }
- /* Destructor. */
- virtual ~function_summary ()
- {
- release ();
- }
- /* Destruction method that can be called for GGT purpose. */
- void release ()
- {
- if (m_symtab_insertion_hook)
- m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
- if (m_symtab_removal_hook)
- m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
- if (m_symtab_duplication_hook)
- m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
- m_symtab_insertion_hook = NULL;
- m_symtab_removal_hook = NULL;
- m_symtab_duplication_hook = NULL;
- /* Release all summaries. */
- typedef typename hash_map <int, T *, summary_hashmap_traits>::iterator map_iterator;
- for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
- release ((*it).second);
- }
- /* 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.traverse <f> (a);
- }
- /* Basic implementation of insert operation. */
- virtual void insert (cgraph_node *, T *) {}
- /* 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 *) {}
- /* Allocates new data that are stored within map. */
- T* allocate_new ()
- {
- return m_ggc ? new (ggc_alloc <T> ()) T() : new T () ;
- }
- /* Release an item that is stored within map. */
- void release (T *item)
- {
- if (m_ggc)
- {
- item->~T ();
- ggc_free (item);
- }
- else
- delete item;
- }
- /* Getter for summary callgraph node pointer. */
- T* get (cgraph_node *node)
- {
- return get (node->summary_uid);
- }
- /* Return number of elements handled by data structure. */
- size_t elements ()
- {
- return m_map.elements ();
- }
- /* Enable insertion hook invocation. */
- void enable_insertion_hook ()
- {
- m_insertion_enabled = true;
- }
- /* Enable insertion hook invocation. */
- void disable_insertion_hook ()
- {
- m_insertion_enabled = false;
- }
- /* Symbol insertion hook that is registered to symbol table. */
- static void symtab_insertion (cgraph_node *node, void *data)
- {
- function_summary *summary = (function_summary <T *> *) (data);
- if (summary->m_insertion_enabled)
- summary->insert (node, summary->get (node));
- }
- /* Symbol removal hook that is registered to symbol table. */
- static void symtab_removal (cgraph_node *node, void *data)
- {
- gcc_checking_assert (node->summary_uid);
- function_summary *summary = (function_summary <T *> *) (data);
- int summary_uid = node->summary_uid;
- T **v = summary->m_map.get (summary_uid);
- if (v)
- {
- summary->remove (node, *v);
- if (!summary->m_ggc)
- delete (*v);
- summary->m_map.remove (summary_uid);
- }
- }
- /* Symbol duplication hook that is registered to symbol table. */
- static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
- void *data)
- {
- function_summary *summary = (function_summary <T *> *) (data);
- T **v = summary->m_map.get (node->summary_uid);
- gcc_checking_assert (node2->summary_uid > 0);
- if (v)
- {
- /* This load is necessary, because we insert a new value! */
- T *data = *v;
- T *duplicate = summary->allocate_new ();
- summary->m_map.put (node2->summary_uid, duplicate);
- summary->duplicate (node, node2, data, duplicate);
- }
- }
- protected:
- /* Indication if we use ggc summary. */
- bool m_ggc;
- private:
- struct summary_hashmap_traits: default_hashmap_traits
- {
- static const int deleted_value = -1;
- static const int empty_value = 0;
- static hashval_t
- hash (const int v)
- {
- return (hashval_t)v;
- }
- template<typename Type>
- static bool
- is_deleted (Type &e)
- {
- return e.m_key == deleted_value;
- }
- template<typename Type>
- static bool
- is_empty (Type &e)
- {
- return e.m_key == empty_value;
- }
- template<typename Type>
- static void
- mark_deleted (Type &e)
- {
- e.m_key = deleted_value;
- }
- template<typename Type>
- static void
- mark_empty (Type &e)
- {
- e.m_key = empty_value;
- }
- };
- /* Getter for summary callgraph ID. */
- T* get (int uid)
- {
- bool existed;
- T **v = &m_map.get_or_insert (uid, &existed);
- if (!existed)
- *v = allocate_new ();
- return *v;
- }
- /* Main summary store, where summary ID is used as key. */
- hash_map <int, T *, summary_hashmap_traits> m_map;
- /* 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;
- /* Indicates if insertion hook is enabled. */
- bool m_insertion_enabled;
- /* Symbol table the summary is registered to. */
- symbol_table *m_symtab;
- 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>
- 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 &summary)
- {
- gcc_checking_assert (summary->m_ggc);
- gt_pch_nx (&summary->m_map);
- }
- template <typename T>
- void
- gt_pch_nx(function_summary<T *>* const& summary, gt_pointer_operator op,
- void *cookie)
- {
- gcc_checking_assert (summary->m_ggc);
- gt_pch_nx (&summary->m_map, op, cookie);
- }
- #endif /* GCC_SYMBOL_SUMMARY_H */
|