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