Mercurial > hg > CbC > CbC_gcc
diff gcc/symbol-summary.h @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/symbol-summary.h Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/symbol-summary.h Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Callgraph summary data structure. - Copyright (C) 2014-2017 Free Software Foundation, Inc. + Copyright (C) 2014-2018 Free Software Foundation, Inc. Contributed by Martin Liska This file is part of GCC. @@ -31,26 +31,23 @@ 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: /* Default construction takes SYMTAB as an argument. */ - function_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc), - m_insertion_enabled (true), m_released (false), m_map (13, ggc), - m_symtab (symtab) - { - 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); - } + function_summary (symbol_table *symtab, bool ggc = false); /* Destructor. */ virtual ~function_summary () @@ -59,22 +56,7 @@ } /* Destruction method that can be called for GGT purpose. */ - void release () - { - if (m_released) - return; - - m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook); - m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook); - m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook); - - /* 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) - release ((*it).second); - - m_released = true; - } + void release (); /* Traverses all summarys with a function F called with ARG as argument. */ @@ -102,22 +84,37 @@ } /* Release an item that is stored within map. */ - void release (T *item) + void release (T *item); + + /* 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) { - if (m_ggc) - { - item->~T (); - ggc_free (item); - } - else - delete item; + bool existed; + T **v = &m_map.get_or_insert (node->get_uid (), &existed); + if (!existed) + *v = allocate_new (); + + return *v; } /* Getter for summary callgraph node pointer. */ - T* get (cgraph_node *node) + T* get (cgraph_node *node) ATTRIBUTE_PURE { - gcc_checking_assert (node->summary_uid); - return get (node->summary_uid); + T **v = m_map.get (node->get_uid ()); + return v == NULL ? NULL : *v; + } + + /* Remove node from summary. */ + void remove (cgraph_node *node) + { + int uid = node->get_uid (); + T **v = m_map.get (uid); + if (v) + { + m_map.remove (uid); + release (*v); + } } /* Return number of elements handled by data structure. */ @@ -129,7 +126,7 @@ /* Return true if a summary for the given NODE already exists. */ bool exists (cgraph_node *node) { - return m_map.get (node->summary_uid) != NULL; + return m_map.get (node->get_uid ()) != NULL; } /* Enable insertion hook invocation. */ @@ -145,50 +142,14 @@ } /* Symbol insertion hook that is registered to symbol table. */ - static void symtab_insertion (cgraph_node *node, void *data) - { - gcc_checking_assert (node->summary_uid); - function_summary *summary = (function_summary <T *> *) (data); - - if (summary->m_insertion_enabled) - summary->insert (node, summary->get (node)); - } + 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) - { - 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); - summary->release (*v); - summary->m_map.remove (summary_uid); - } - } + 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) - { - 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); - } - } + void *data); protected: /* Indication if we use ggc summary. */ @@ -197,17 +158,6 @@ private: typedef int_hash <int, 0, -1> map_hash; - /* 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; - } - /* Indicates if insertion hook is enabled. */ bool m_insertion_enabled; /* Indicates if the summary is released. */ @@ -230,6 +180,103 @@ }; template <typename T> +function_summary<T *>::function_summary (symbol_table *symtab, bool ggc): + m_ggc (ggc), m_insertion_enabled (true), m_released (false), m_map (13, ggc), + m_symtab (symtab) +{ + 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); +} + +template <typename T> +void +function_summary<T *>::release () +{ + if (m_released) + return; + + m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook); + m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook); + m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook); + + /* 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) + release ((*it).second); + + m_released = true; +} + +template <typename T> +void +function_summary<T *>::release (T *item) +{ + if (m_ggc) + { + item->~T (); + ggc_free (item); + } + else + delete item; +} + +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); + + if (summary->m_insertion_enabled) + 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); + + int uid = node->get_uid (); + T **v = summary->m_map.get (uid); + + if (v) + { + summary->remove (node, *v); + + if (!summary->m_ggc) + delete (*v); + + summary->m_map.remove (uid); + } +} + +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) + { + /* This load is necessary, because we insert a new value! */ + T *duplicate = summary->allocate_new (); + summary->m_map.put (node2->get_uid (), duplicate); + summary->duplicate (node, node2, v, duplicate); + } +} + +template <typename T> void gt_ggc_mx(function_summary<T *>* const &summary) { @@ -272,7 +319,8 @@ public: /* Default construction takes SYMTAB as an argument. */ call_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc), - m_map (13, ggc), m_released (false), m_symtab (symtab) + m_initialize_when_cloning (false), m_map (13, ggc), m_released (false), + m_symtab (symtab) { m_symtab_removal_hook = symtab->add_edge_removal_hook @@ -289,21 +337,7 @@ } /* Destruction method that can be called for GGT purpose. */ - void release () - { - if (m_released) - return; - - m_symtab->remove_edge_removal_hook (m_symtab_removal_hook); - m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook); - - /* 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) - release ((*it).second); - - m_released = true; - } + void release (); /* Traverses all summarys with a function F called with ARG as argument. */ @@ -328,21 +362,37 @@ } /* Release an item that is stored within map. */ - void release (T *item) + void release (T *item); + + /* 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) { - if (m_ggc) - { - item->~T (); - ggc_free (item); - } - else - delete item; + bool existed; + T **v = &m_map.get_or_insert (edge->get_uid (), &existed); + if (!existed) + *v = allocate_new (); + + return *v; } /* Getter for summary callgraph edge pointer. */ - T* get (cgraph_edge *edge) + T* get (cgraph_edge *edge) ATTRIBUTE_PURE { - return get (hashable_uid (edge)); + T **v = m_map.get (edge->get_uid ()); + return v == NULL ? NULL : *v; + } + + /* Remove edge from summary. */ + void remove (cgraph_edge *edge) + { + int uid = edge->get_uid (); + T **v = m_map.get (uid); + if (v) + { + m_map.remove (uid); + release (*v); + } } /* Return number of elements handled by data structure. */ @@ -354,67 +404,26 @@ /* Return true if a summary for the given EDGE already exists. */ bool exists (cgraph_edge *edge) { - return m_map.get (hashable_uid (edge)) != NULL; + 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) - { - call_summary *summary = (call_summary <T *> *) (data); - - int h_uid = summary->hashable_uid (edge); - T **v = summary->m_map.get (h_uid); - - if (v) - { - summary->remove (edge, *v); - summary->release (*v); - summary->m_map.remove (h_uid); - } - } + 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) - { - call_summary *summary = (call_summary <T *> *) (data); - T **v = summary->m_map.get (summary->hashable_uid (edge1)); - - if (v) - { - /* This load is necessary, because we insert a new value! */ - T *data = *v; - T *duplicate = summary->allocate_new (); - summary->m_map.put (summary->hashable_uid (edge2), duplicate); - summary->duplicate (edge1, edge2, data, duplicate); - } - } + void *data); protected: /* Indication if we use ggc summary. */ bool m_ggc; + /* Initialize summary for an edge that is cloned. */ + bool m_initialize_when_cloning; + private: typedef int_hash <int, 0, -1> map_hash; - /* 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; - } - - /* Get a hashable uid of EDGE. */ - int hashable_uid (cgraph_edge *edge) - { - /* Edge uids start at zero which our hash_map does not like. */ - return edge->uid + 1; - } - /* Main summary store, where summary ID is used as key. */ hash_map <map_hash, T *> m_map; /* Internal summary removal hook pointer. */ @@ -434,6 +443,82 @@ template <typename T> void +call_summary<T *>::release () +{ + if (m_released) + return; + + m_symtab->remove_edge_removal_hook (m_symtab_removal_hook); + m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook); + + /* 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) + release ((*it).second); + + m_released = true; +} + +template <typename T> +void +call_summary<T *>::release (T *item) +{ + if (m_ggc) + { + item->~T (); + ggc_free (item); + } + else + delete item; +} + +template <typename T> +void +call_summary<T *>::symtab_removal (cgraph_edge *edge, void *data) +{ + call_summary *summary = (call_summary <T *> *) (data); + + int h_uid = edge->get_uid (); + T **v = summary->m_map.get (h_uid); + + if (v) + { + summary->remove (edge, *v); + summary->release (*v); + summary->m_map.remove (h_uid); + } +} + +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 + { + T **v = summary->m_map.get (edge1->get_uid ()); + if (v) + { + /* This load is necessary, because we insert a new value! */ + edge1_summary = *v; + } + } + + if (edge1_summary) + { + T *duplicate = summary->allocate_new (); + summary->m_map.put (edge2->get_uid (), duplicate); + summary->duplicate (edge1, edge2, edge1_summary, duplicate); + } +} + +template <typename T> +void gt_ggc_mx(call_summary<T *>* const &summary) { gcc_checking_assert (summary->m_ggc);