]>
Commit | Line | Data |
---|---|---|
4008290f | 1 | /* Callgraph summary data structure. |
cbe34bb5 | 2 | Copyright (C) 2014-2017 Free Software Foundation, Inc. |
4008290f ML |
3 | Contributed by Martin Liska |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify it under | |
8 | the terms of the GNU General Public License as published by the Free | |
9 | Software Foundation; either version 3, or (at your option) any later | |
10 | version. | |
11 | ||
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GCC; see the file COPYING3. If not see | |
19 | <http://www.gnu.org/licenses/>. */ | |
20 | ||
21 | #ifndef GCC_SYMBOL_SUMMARY_H | |
22 | #define GCC_SYMBOL_SUMMARY_H | |
23 | ||
24 | /* We want to pass just pointer types as argument for function_summary | |
25 | template class. */ | |
26 | ||
27 | template <class T> | |
28 | class function_summary | |
29 | { | |
30 | private: | |
31 | function_summary(); | |
32 | }; | |
33 | ||
34 | template <class T> | |
35 | class GTY((user)) function_summary <T *> | |
36 | { | |
37 | public: | |
38 | /* Default construction takes SYMTAB as an argument. */ | |
39 | function_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc), | |
34e82342 | 40 | m_insertion_enabled (true), m_released (false), m_map (13, ggc), |
e806796d | 41 | m_symtab (symtab) |
4008290f | 42 | { |
4008290f ML |
43 | m_symtab_insertion_hook = |
44 | symtab->add_cgraph_insertion_hook | |
45 | (function_summary::symtab_insertion, this); | |
46 | ||
47 | m_symtab_removal_hook = | |
48 | symtab->add_cgraph_removal_hook | |
49 | (function_summary::symtab_removal, this); | |
50 | m_symtab_duplication_hook = | |
51 | symtab->add_cgraph_duplication_hook | |
52 | (function_summary::symtab_duplication, this); | |
53 | } | |
54 | ||
55 | /* Destructor. */ | |
56 | virtual ~function_summary () | |
57 | { | |
58 | release (); | |
59 | } | |
60 | ||
61 | /* Destruction method that can be called for GGT purpose. */ | |
62 | void release () | |
63 | { | |
e806796d ML |
64 | if (m_released) |
65 | return; | |
4008290f | 66 | |
e806796d ML |
67 | m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook); |
68 | m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook); | |
69 | m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook); | |
fdbdc4b5 ML |
70 | |
71 | /* Release all summaries. */ | |
fb5c464a | 72 | typedef typename hash_map <map_hash, T *>::iterator map_iterator; |
fdbdc4b5 ML |
73 | for (map_iterator it = m_map.begin (); it != m_map.end (); ++it) |
74 | release ((*it).second); | |
e806796d ML |
75 | |
76 | m_released = true; | |
4008290f ML |
77 | } |
78 | ||
79 | /* Traverses all summarys with a function F called with | |
80 | ARG as argument. */ | |
81 | template<typename Arg, bool (*f)(const T &, Arg)> | |
82 | void traverse (Arg a) const | |
83 | { | |
84 | m_map.traverse <f> (a); | |
85 | } | |
86 | ||
87 | /* Basic implementation of insert operation. */ | |
88 | virtual void insert (cgraph_node *, T *) {} | |
89 | ||
90 | /* Basic implementation of removal operation. */ | |
91 | virtual void remove (cgraph_node *, T *) {} | |
92 | ||
93 | /* Basic implementation of duplication operation. */ | |
94 | virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {} | |
95 | ||
96 | /* Allocates new data that are stored within map. */ | |
97 | T* allocate_new () | |
98 | { | |
e806796d ML |
99 | /* Call gcc_internal_because we do not want to call finalizer for |
100 | a type T. We call dtor explicitly. */ | |
101 | return m_ggc ? new (ggc_internal_alloc (sizeof (T))) T () : new T () ; | |
4008290f ML |
102 | } |
103 | ||
fdbdc4b5 ML |
104 | /* Release an item that is stored within map. */ |
105 | void release (T *item) | |
106 | { | |
107 | if (m_ggc) | |
108 | { | |
109 | item->~T (); | |
110 | ggc_free (item); | |
111 | } | |
112 | else | |
113 | delete item; | |
114 | } | |
115 | ||
4008290f ML |
116 | /* Getter for summary callgraph node pointer. */ |
117 | T* get (cgraph_node *node) | |
118 | { | |
0ec955c2 | 119 | gcc_checking_assert (node->summary_uid); |
4008290f ML |
120 | return get (node->summary_uid); |
121 | } | |
122 | ||
123 | /* Return number of elements handled by data structure. */ | |
124 | size_t elements () | |
125 | { | |
126 | return m_map.elements (); | |
127 | } | |
128 | ||
129 | /* Enable insertion hook invocation. */ | |
130 | void enable_insertion_hook () | |
131 | { | |
132 | m_insertion_enabled = true; | |
133 | } | |
134 | ||
135 | /* Enable insertion hook invocation. */ | |
136 | void disable_insertion_hook () | |
137 | { | |
138 | m_insertion_enabled = false; | |
139 | } | |
140 | ||
141 | /* Symbol insertion hook that is registered to symbol table. */ | |
142 | static void symtab_insertion (cgraph_node *node, void *data) | |
143 | { | |
0ec955c2 | 144 | gcc_checking_assert (node->summary_uid); |
4008290f ML |
145 | function_summary *summary = (function_summary <T *> *) (data); |
146 | ||
147 | if (summary->m_insertion_enabled) | |
148 | summary->insert (node, summary->get (node)); | |
149 | } | |
150 | ||
151 | /* Symbol removal hook that is registered to symbol table. */ | |
152 | static void symtab_removal (cgraph_node *node, void *data) | |
153 | { | |
154 | gcc_checking_assert (node->summary_uid); | |
155 | function_summary *summary = (function_summary <T *> *) (data); | |
156 | ||
157 | int summary_uid = node->summary_uid; | |
158 | T **v = summary->m_map.get (summary_uid); | |
159 | ||
160 | if (v) | |
161 | { | |
162 | summary->remove (node, *v); | |
163 | ||
164 | if (!summary->m_ggc) | |
165 | delete (*v); | |
166 | ||
167 | summary->m_map.remove (summary_uid); | |
168 | } | |
169 | } | |
170 | ||
171 | /* Symbol duplication hook that is registered to symbol table. */ | |
172 | static void symtab_duplication (cgraph_node *node, cgraph_node *node2, | |
173 | void *data) | |
174 | { | |
175 | function_summary *summary = (function_summary <T *> *) (data); | |
176 | T **v = summary->m_map.get (node->summary_uid); | |
177 | ||
178 | gcc_checking_assert (node2->summary_uid > 0); | |
179 | ||
180 | if (v) | |
181 | { | |
182 | /* This load is necessary, because we insert a new value! */ | |
183 | T *data = *v; | |
184 | T *duplicate = summary->allocate_new (); | |
185 | summary->m_map.put (node2->summary_uid, duplicate); | |
186 | summary->duplicate (node, node2, data, duplicate); | |
187 | } | |
188 | } | |
189 | ||
190 | protected: | |
191 | /* Indication if we use ggc summary. */ | |
192 | bool m_ggc; | |
193 | ||
194 | private: | |
e0702244 | 195 | typedef int_hash <int, 0, -1> map_hash; |
4008290f ML |
196 | |
197 | /* Getter for summary callgraph ID. */ | |
198 | T* get (int uid) | |
199 | { | |
200 | bool existed; | |
201 | T **v = &m_map.get_or_insert (uid, &existed); | |
202 | if (!existed) | |
203 | *v = allocate_new (); | |
204 | ||
205 | return *v; | |
206 | } | |
207 | ||
34e82342 RB |
208 | /* Indicates if insertion hook is enabled. */ |
209 | bool m_insertion_enabled; | |
210 | /* Indicates if the summary is released. */ | |
211 | bool m_released; | |
4008290f | 212 | /* Main summary store, where summary ID is used as key. */ |
fb5c464a | 213 | hash_map <map_hash, T *> m_map; |
4008290f ML |
214 | /* Internal summary insertion hook pointer. */ |
215 | cgraph_node_hook_list *m_symtab_insertion_hook; | |
216 | /* Internal summary removal hook pointer. */ | |
217 | cgraph_node_hook_list *m_symtab_removal_hook; | |
218 | /* Internal summary duplication hook pointer. */ | |
219 | cgraph_2node_hook_list *m_symtab_duplication_hook; | |
4008290f ML |
220 | /* Symbol table the summary is registered to. */ |
221 | symbol_table *m_symtab; | |
222 | ||
223 | template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &); | |
224 | template <typename U> friend void gt_pch_nx (function_summary <U *> * const &); | |
225 | template <typename U> friend void gt_pch_nx (function_summary <U *> * const &, | |
226 | gt_pointer_operator, void *); | |
227 | }; | |
228 | ||
229 | template <typename T> | |
230 | void | |
231 | gt_ggc_mx(function_summary<T *>* const &summary) | |
232 | { | |
233 | gcc_checking_assert (summary->m_ggc); | |
234 | gt_ggc_mx (&summary->m_map); | |
235 | } | |
236 | ||
237 | template <typename T> | |
238 | void | |
239 | gt_pch_nx(function_summary<T *>* const &summary) | |
240 | { | |
241 | gcc_checking_assert (summary->m_ggc); | |
242 | gt_pch_nx (&summary->m_map); | |
243 | } | |
244 | ||
245 | template <typename T> | |
246 | void | |
247 | gt_pch_nx(function_summary<T *>* const& summary, gt_pointer_operator op, | |
248 | void *cookie) | |
249 | { | |
250 | gcc_checking_assert (summary->m_ggc); | |
251 | gt_pch_nx (&summary->m_map, op, cookie); | |
252 | } | |
253 | ||
254 | #endif /* GCC_SYMBOL_SUMMARY_H */ |