Mercurial > hg > CbC > CbC_gcc
comparison gcc/symbol-summary.h @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Callgraph summary data structure. | 1 /* Callgraph summary data structure. |
2 Copyright (C) 2014-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2014-2018 Free Software Foundation, Inc. |
3 Contributed by Martin Liska | 3 Contributed by Martin Liska |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
29 { | 29 { |
30 private: | 30 private: |
31 function_summary(); | 31 function_summary(); |
32 }; | 32 }; |
33 | 33 |
34 /* Function summary is a helper class that is used to associate a data structure | |
35 related to a callgraph node. Typical usage can be seen in IPA passes which | |
36 create a temporary pass-related structures. The summary class registers | |
37 hooks that are triggered when a new node is inserted, duplicated and deleted. | |
38 A user of a summary class can ovewrite virtual methods than are triggered by | |
39 the summary if such hook is triggered. Apart from a callgraph node, the user | |
40 is given a data structure tied to the node. | |
41 | |
42 The function summary class can work both with a heap-allocated memory and | |
43 a memory gained by garbage collected memory. */ | |
44 | |
34 template <class T> | 45 template <class T> |
35 class GTY((user)) function_summary <T *> | 46 class GTY((user)) function_summary <T *> |
36 { | 47 { |
37 public: | 48 public: |
38 /* Default construction takes SYMTAB as an argument. */ | 49 /* Default construction takes SYMTAB as an argument. */ |
39 function_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc), | 50 function_summary (symbol_table *symtab, bool ggc = false); |
40 m_insertion_enabled (true), m_released (false), m_map (13, ggc), | |
41 m_symtab (symtab) | |
42 { | |
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 | 51 |
55 /* Destructor. */ | 52 /* Destructor. */ |
56 virtual ~function_summary () | 53 virtual ~function_summary () |
57 { | 54 { |
58 release (); | 55 release (); |
59 } | 56 } |
60 | 57 |
61 /* Destruction method that can be called for GGT purpose. */ | 58 /* Destruction method that can be called for GGT purpose. */ |
62 void release () | 59 void release (); |
63 { | |
64 if (m_released) | |
65 return; | |
66 | |
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); | |
70 | |
71 /* Release all summaries. */ | |
72 typedef typename hash_map <map_hash, T *>::iterator map_iterator; | |
73 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it) | |
74 release ((*it).second); | |
75 | |
76 m_released = true; | |
77 } | |
78 | 60 |
79 /* Traverses all summarys with a function F called with | 61 /* Traverses all summarys with a function F called with |
80 ARG as argument. */ | 62 ARG as argument. */ |
81 template<typename Arg, bool (*f)(const T &, Arg)> | 63 template<typename Arg, bool (*f)(const T &, Arg)> |
82 void traverse (Arg a) const | 64 void traverse (Arg a) const |
100 a type T. We call dtor explicitly. */ | 82 a type T. We call dtor explicitly. */ |
101 return m_ggc ? new (ggc_internal_alloc (sizeof (T))) T () : new T () ; | 83 return m_ggc ? new (ggc_internal_alloc (sizeof (T))) T () : new T () ; |
102 } | 84 } |
103 | 85 |
104 /* Release an item that is stored within map. */ | 86 /* Release an item that is stored within map. */ |
105 void release (T *item) | 87 void release (T *item); |
106 { | 88 |
107 if (m_ggc) | 89 /* Getter for summary callgraph node pointer. If a summary for a node |
90 does not exist it will be created. */ | |
91 T* get_create (cgraph_node *node) | |
92 { | |
93 bool existed; | |
94 T **v = &m_map.get_or_insert (node->get_uid (), &existed); | |
95 if (!existed) | |
96 *v = allocate_new (); | |
97 | |
98 return *v; | |
99 } | |
100 | |
101 /* Getter for summary callgraph node pointer. */ | |
102 T* get (cgraph_node *node) ATTRIBUTE_PURE | |
103 { | |
104 T **v = m_map.get (node->get_uid ()); | |
105 return v == NULL ? NULL : *v; | |
106 } | |
107 | |
108 /* Remove node from summary. */ | |
109 void remove (cgraph_node *node) | |
110 { | |
111 int uid = node->get_uid (); | |
112 T **v = m_map.get (uid); | |
113 if (v) | |
108 { | 114 { |
109 item->~T (); | 115 m_map.remove (uid); |
110 ggc_free (item); | 116 release (*v); |
111 } | 117 } |
112 else | |
113 delete item; | |
114 } | |
115 | |
116 /* Getter for summary callgraph node pointer. */ | |
117 T* get (cgraph_node *node) | |
118 { | |
119 gcc_checking_assert (node->summary_uid); | |
120 return get (node->summary_uid); | |
121 } | 118 } |
122 | 119 |
123 /* Return number of elements handled by data structure. */ | 120 /* Return number of elements handled by data structure. */ |
124 size_t elements () | 121 size_t elements () |
125 { | 122 { |
127 } | 124 } |
128 | 125 |
129 /* Return true if a summary for the given NODE already exists. */ | 126 /* Return true if a summary for the given NODE already exists. */ |
130 bool exists (cgraph_node *node) | 127 bool exists (cgraph_node *node) |
131 { | 128 { |
132 return m_map.get (node->summary_uid) != NULL; | 129 return m_map.get (node->get_uid ()) != NULL; |
133 } | 130 } |
134 | 131 |
135 /* Enable insertion hook invocation. */ | 132 /* Enable insertion hook invocation. */ |
136 void enable_insertion_hook () | 133 void enable_insertion_hook () |
137 { | 134 { |
143 { | 140 { |
144 m_insertion_enabled = false; | 141 m_insertion_enabled = false; |
145 } | 142 } |
146 | 143 |
147 /* Symbol insertion hook that is registered to symbol table. */ | 144 /* Symbol insertion hook that is registered to symbol table. */ |
148 static void symtab_insertion (cgraph_node *node, void *data) | 145 static void symtab_insertion (cgraph_node *node, void *data); |
149 { | |
150 gcc_checking_assert (node->summary_uid); | |
151 function_summary *summary = (function_summary <T *> *) (data); | |
152 | |
153 if (summary->m_insertion_enabled) | |
154 summary->insert (node, summary->get (node)); | |
155 } | |
156 | 146 |
157 /* Symbol removal hook that is registered to symbol table. */ | 147 /* Symbol removal hook that is registered to symbol table. */ |
158 static void symtab_removal (cgraph_node *node, void *data) | 148 static void symtab_removal (cgraph_node *node, void *data); |
159 { | |
160 gcc_checking_assert (node->summary_uid); | |
161 function_summary *summary = (function_summary <T *> *) (data); | |
162 | |
163 int summary_uid = node->summary_uid; | |
164 T **v = summary->m_map.get (summary_uid); | |
165 | |
166 if (v) | |
167 { | |
168 summary->remove (node, *v); | |
169 summary->release (*v); | |
170 summary->m_map.remove (summary_uid); | |
171 } | |
172 } | |
173 | 149 |
174 /* Symbol duplication hook that is registered to symbol table. */ | 150 /* Symbol duplication hook that is registered to symbol table. */ |
175 static void symtab_duplication (cgraph_node *node, cgraph_node *node2, | 151 static void symtab_duplication (cgraph_node *node, cgraph_node *node2, |
176 void *data) | 152 void *data); |
177 { | |
178 function_summary *summary = (function_summary <T *> *) (data); | |
179 T **v = summary->m_map.get (node->summary_uid); | |
180 | |
181 gcc_checking_assert (node2->summary_uid > 0); | |
182 | |
183 if (v) | |
184 { | |
185 /* This load is necessary, because we insert a new value! */ | |
186 T *data = *v; | |
187 T *duplicate = summary->allocate_new (); | |
188 summary->m_map.put (node2->summary_uid, duplicate); | |
189 summary->duplicate (node, node2, data, duplicate); | |
190 } | |
191 } | |
192 | 153 |
193 protected: | 154 protected: |
194 /* Indication if we use ggc summary. */ | 155 /* Indication if we use ggc summary. */ |
195 bool m_ggc; | 156 bool m_ggc; |
196 | 157 |
197 private: | 158 private: |
198 typedef int_hash <int, 0, -1> map_hash; | 159 typedef int_hash <int, 0, -1> map_hash; |
199 | |
200 /* Getter for summary callgraph ID. */ | |
201 T* get (int uid) | |
202 { | |
203 bool existed; | |
204 T **v = &m_map.get_or_insert (uid, &existed); | |
205 if (!existed) | |
206 *v = allocate_new (); | |
207 | |
208 return *v; | |
209 } | |
210 | 160 |
211 /* Indicates if insertion hook is enabled. */ | 161 /* Indicates if insertion hook is enabled. */ |
212 bool m_insertion_enabled; | 162 bool m_insertion_enabled; |
213 /* Indicates if the summary is released. */ | 163 /* Indicates if the summary is released. */ |
214 bool m_released; | 164 bool m_released; |
228 template <typename U> friend void gt_pch_nx (function_summary <U *> * const &, | 178 template <typename U> friend void gt_pch_nx (function_summary <U *> * const &, |
229 gt_pointer_operator, void *); | 179 gt_pointer_operator, void *); |
230 }; | 180 }; |
231 | 181 |
232 template <typename T> | 182 template <typename T> |
183 function_summary<T *>::function_summary (symbol_table *symtab, bool ggc): | |
184 m_ggc (ggc), m_insertion_enabled (true), m_released (false), m_map (13, ggc), | |
185 m_symtab (symtab) | |
186 { | |
187 m_symtab_insertion_hook | |
188 = symtab->add_cgraph_insertion_hook (function_summary::symtab_insertion, | |
189 this); | |
190 | |
191 m_symtab_removal_hook | |
192 = symtab->add_cgraph_removal_hook (function_summary::symtab_removal, this); | |
193 m_symtab_duplication_hook | |
194 = symtab->add_cgraph_duplication_hook (function_summary::symtab_duplication, | |
195 this); | |
196 } | |
197 | |
198 template <typename T> | |
199 void | |
200 function_summary<T *>::release () | |
201 { | |
202 if (m_released) | |
203 return; | |
204 | |
205 m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook); | |
206 m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook); | |
207 m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook); | |
208 | |
209 /* Release all summaries. */ | |
210 typedef typename hash_map <map_hash, T *>::iterator map_iterator; | |
211 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it) | |
212 release ((*it).second); | |
213 | |
214 m_released = true; | |
215 } | |
216 | |
217 template <typename T> | |
218 void | |
219 function_summary<T *>::release (T *item) | |
220 { | |
221 if (m_ggc) | |
222 { | |
223 item->~T (); | |
224 ggc_free (item); | |
225 } | |
226 else | |
227 delete item; | |
228 } | |
229 | |
230 template <typename T> | |
231 void | |
232 function_summary<T *>::symtab_insertion (cgraph_node *node, void *data) | |
233 { | |
234 gcc_checking_assert (node->get_uid ()); | |
235 function_summary *summary = (function_summary <T *> *) (data); | |
236 | |
237 if (summary->m_insertion_enabled) | |
238 summary->insert (node, summary->get_create (node)); | |
239 } | |
240 | |
241 template <typename T> | |
242 void | |
243 function_summary<T *>::symtab_removal (cgraph_node *node, void *data) | |
244 { | |
245 gcc_checking_assert (node->get_uid ()); | |
246 function_summary *summary = (function_summary <T *> *) (data); | |
247 | |
248 int uid = node->get_uid (); | |
249 T **v = summary->m_map.get (uid); | |
250 | |
251 if (v) | |
252 { | |
253 summary->remove (node, *v); | |
254 | |
255 if (!summary->m_ggc) | |
256 delete (*v); | |
257 | |
258 summary->m_map.remove (uid); | |
259 } | |
260 } | |
261 | |
262 template <typename T> | |
263 void | |
264 function_summary<T *>::symtab_duplication (cgraph_node *node, | |
265 cgraph_node *node2, void *data) | |
266 { | |
267 function_summary *summary = (function_summary <T *> *) (data); | |
268 T *v = summary->get (node); | |
269 | |
270 if (v) | |
271 { | |
272 /* This load is necessary, because we insert a new value! */ | |
273 T *duplicate = summary->allocate_new (); | |
274 summary->m_map.put (node2->get_uid (), duplicate); | |
275 summary->duplicate (node, node2, v, duplicate); | |
276 } | |
277 } | |
278 | |
279 template <typename T> | |
233 void | 280 void |
234 gt_ggc_mx(function_summary<T *>* const &summary) | 281 gt_ggc_mx(function_summary<T *>* const &summary) |
235 { | 282 { |
236 gcc_checking_assert (summary->m_ggc); | 283 gcc_checking_assert (summary->m_ggc); |
237 gt_ggc_mx (&summary->m_map); | 284 gt_ggc_mx (&summary->m_map); |
270 class GTY((user)) call_summary <T *> | 317 class GTY((user)) call_summary <T *> |
271 { | 318 { |
272 public: | 319 public: |
273 /* Default construction takes SYMTAB as an argument. */ | 320 /* Default construction takes SYMTAB as an argument. */ |
274 call_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc), | 321 call_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc), |
275 m_map (13, ggc), m_released (false), m_symtab (symtab) | 322 m_initialize_when_cloning (false), m_map (13, ggc), m_released (false), |
323 m_symtab (symtab) | |
276 { | 324 { |
277 m_symtab_removal_hook = | 325 m_symtab_removal_hook = |
278 symtab->add_edge_removal_hook | 326 symtab->add_edge_removal_hook |
279 (call_summary::symtab_removal, this); | 327 (call_summary::symtab_removal, this); |
280 m_symtab_duplication_hook = | 328 m_symtab_duplication_hook = |
287 { | 335 { |
288 release (); | 336 release (); |
289 } | 337 } |
290 | 338 |
291 /* Destruction method that can be called for GGT purpose. */ | 339 /* Destruction method that can be called for GGT purpose. */ |
292 void release () | 340 void release (); |
293 { | |
294 if (m_released) | |
295 return; | |
296 | |
297 m_symtab->remove_edge_removal_hook (m_symtab_removal_hook); | |
298 m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook); | |
299 | |
300 /* Release all summaries. */ | |
301 typedef typename hash_map <map_hash, T *>::iterator map_iterator; | |
302 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it) | |
303 release ((*it).second); | |
304 | |
305 m_released = true; | |
306 } | |
307 | 341 |
308 /* Traverses all summarys with a function F called with | 342 /* Traverses all summarys with a function F called with |
309 ARG as argument. */ | 343 ARG as argument. */ |
310 template<typename Arg, bool (*f)(const T &, Arg)> | 344 template<typename Arg, bool (*f)(const T &, Arg)> |
311 void traverse (Arg a) const | 345 void traverse (Arg a) const |
326 a type T. We call dtor explicitly. */ | 360 a type T. We call dtor explicitly. */ |
327 return m_ggc ? new (ggc_internal_alloc (sizeof (T))) T () : new T () ; | 361 return m_ggc ? new (ggc_internal_alloc (sizeof (T))) T () : new T () ; |
328 } | 362 } |
329 | 363 |
330 /* Release an item that is stored within map. */ | 364 /* Release an item that is stored within map. */ |
331 void release (T *item) | 365 void release (T *item); |
332 { | 366 |
333 if (m_ggc) | 367 /* Getter for summary callgraph edge pointer. |
368 If a summary for an edge does not exist, it will be created. */ | |
369 T* get_create (cgraph_edge *edge) | |
370 { | |
371 bool existed; | |
372 T **v = &m_map.get_or_insert (edge->get_uid (), &existed); | |
373 if (!existed) | |
374 *v = allocate_new (); | |
375 | |
376 return *v; | |
377 } | |
378 | |
379 /* Getter for summary callgraph edge pointer. */ | |
380 T* get (cgraph_edge *edge) ATTRIBUTE_PURE | |
381 { | |
382 T **v = m_map.get (edge->get_uid ()); | |
383 return v == NULL ? NULL : *v; | |
384 } | |
385 | |
386 /* Remove edge from summary. */ | |
387 void remove (cgraph_edge *edge) | |
388 { | |
389 int uid = edge->get_uid (); | |
390 T **v = m_map.get (uid); | |
391 if (v) | |
334 { | 392 { |
335 item->~T (); | 393 m_map.remove (uid); |
336 ggc_free (item); | 394 release (*v); |
337 } | 395 } |
338 else | |
339 delete item; | |
340 } | |
341 | |
342 /* Getter for summary callgraph edge pointer. */ | |
343 T* get (cgraph_edge *edge) | |
344 { | |
345 return get (hashable_uid (edge)); | |
346 } | 396 } |
347 | 397 |
348 /* Return number of elements handled by data structure. */ | 398 /* Return number of elements handled by data structure. */ |
349 size_t elements () | 399 size_t elements () |
350 { | 400 { |
352 } | 402 } |
353 | 403 |
354 /* Return true if a summary for the given EDGE already exists. */ | 404 /* Return true if a summary for the given EDGE already exists. */ |
355 bool exists (cgraph_edge *edge) | 405 bool exists (cgraph_edge *edge) |
356 { | 406 { |
357 return m_map.get (hashable_uid (edge)) != NULL; | 407 return m_map.get (edge->get_uid ()) != NULL; |
358 } | 408 } |
359 | 409 |
360 /* Symbol removal hook that is registered to symbol table. */ | 410 /* Symbol removal hook that is registered to symbol table. */ |
361 static void symtab_removal (cgraph_edge *edge, void *data) | 411 static void symtab_removal (cgraph_edge *edge, void *data); |
362 { | |
363 call_summary *summary = (call_summary <T *> *) (data); | |
364 | |
365 int h_uid = summary->hashable_uid (edge); | |
366 T **v = summary->m_map.get (h_uid); | |
367 | |
368 if (v) | |
369 { | |
370 summary->remove (edge, *v); | |
371 summary->release (*v); | |
372 summary->m_map.remove (h_uid); | |
373 } | |
374 } | |
375 | 412 |
376 /* Symbol duplication hook that is registered to symbol table. */ | 413 /* Symbol duplication hook that is registered to symbol table. */ |
377 static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2, | 414 static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2, |
378 void *data) | 415 void *data); |
379 { | |
380 call_summary *summary = (call_summary <T *> *) (data); | |
381 T **v = summary->m_map.get (summary->hashable_uid (edge1)); | |
382 | |
383 if (v) | |
384 { | |
385 /* This load is necessary, because we insert a new value! */ | |
386 T *data = *v; | |
387 T *duplicate = summary->allocate_new (); | |
388 summary->m_map.put (summary->hashable_uid (edge2), duplicate); | |
389 summary->duplicate (edge1, edge2, data, duplicate); | |
390 } | |
391 } | |
392 | 416 |
393 protected: | 417 protected: |
394 /* Indication if we use ggc summary. */ | 418 /* Indication if we use ggc summary. */ |
395 bool m_ggc; | 419 bool m_ggc; |
396 | 420 |
421 /* Initialize summary for an edge that is cloned. */ | |
422 bool m_initialize_when_cloning; | |
423 | |
397 private: | 424 private: |
398 typedef int_hash <int, 0, -1> map_hash; | 425 typedef int_hash <int, 0, -1> map_hash; |
399 | |
400 /* Getter for summary callgraph ID. */ | |
401 T* get (int uid) | |
402 { | |
403 bool existed; | |
404 T **v = &m_map.get_or_insert (uid, &existed); | |
405 if (!existed) | |
406 *v = allocate_new (); | |
407 | |
408 return *v; | |
409 } | |
410 | |
411 /* Get a hashable uid of EDGE. */ | |
412 int hashable_uid (cgraph_edge *edge) | |
413 { | |
414 /* Edge uids start at zero which our hash_map does not like. */ | |
415 return edge->uid + 1; | |
416 } | |
417 | 426 |
418 /* Main summary store, where summary ID is used as key. */ | 427 /* Main summary store, where summary ID is used as key. */ |
419 hash_map <map_hash, T *> m_map; | 428 hash_map <map_hash, T *> m_map; |
420 /* Internal summary removal hook pointer. */ | 429 /* Internal summary removal hook pointer. */ |
421 cgraph_edge_hook_list *m_symtab_removal_hook; | 430 cgraph_edge_hook_list *m_symtab_removal_hook; |
432 gt_pointer_operator, void *); | 441 gt_pointer_operator, void *); |
433 }; | 442 }; |
434 | 443 |
435 template <typename T> | 444 template <typename T> |
436 void | 445 void |
446 call_summary<T *>::release () | |
447 { | |
448 if (m_released) | |
449 return; | |
450 | |
451 m_symtab->remove_edge_removal_hook (m_symtab_removal_hook); | |
452 m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook); | |
453 | |
454 /* Release all summaries. */ | |
455 typedef typename hash_map <map_hash, T *>::iterator map_iterator; | |
456 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it) | |
457 release ((*it).second); | |
458 | |
459 m_released = true; | |
460 } | |
461 | |
462 template <typename T> | |
463 void | |
464 call_summary<T *>::release (T *item) | |
465 { | |
466 if (m_ggc) | |
467 { | |
468 item->~T (); | |
469 ggc_free (item); | |
470 } | |
471 else | |
472 delete item; | |
473 } | |
474 | |
475 template <typename T> | |
476 void | |
477 call_summary<T *>::symtab_removal (cgraph_edge *edge, void *data) | |
478 { | |
479 call_summary *summary = (call_summary <T *> *) (data); | |
480 | |
481 int h_uid = edge->get_uid (); | |
482 T **v = summary->m_map.get (h_uid); | |
483 | |
484 if (v) | |
485 { | |
486 summary->remove (edge, *v); | |
487 summary->release (*v); | |
488 summary->m_map.remove (h_uid); | |
489 } | |
490 } | |
491 | |
492 template <typename T> | |
493 void | |
494 call_summary<T *>::symtab_duplication (cgraph_edge *edge1, | |
495 cgraph_edge *edge2, void *data) | |
496 { | |
497 call_summary *summary = (call_summary <T *> *) (data); | |
498 T *edge1_summary = NULL; | |
499 | |
500 if (summary->m_initialize_when_cloning) | |
501 edge1_summary = summary->get_create (edge1); | |
502 else | |
503 { | |
504 T **v = summary->m_map.get (edge1->get_uid ()); | |
505 if (v) | |
506 { | |
507 /* This load is necessary, because we insert a new value! */ | |
508 edge1_summary = *v; | |
509 } | |
510 } | |
511 | |
512 if (edge1_summary) | |
513 { | |
514 T *duplicate = summary->allocate_new (); | |
515 summary->m_map.put (edge2->get_uid (), duplicate); | |
516 summary->duplicate (edge1, edge2, edge1_summary, duplicate); | |
517 } | |
518 } | |
519 | |
520 template <typename T> | |
521 void | |
437 gt_ggc_mx(call_summary<T *>* const &summary) | 522 gt_ggc_mx(call_summary<T *>* const &summary) |
438 { | 523 { |
439 gcc_checking_assert (summary->m_ggc); | 524 gcc_checking_assert (summary->m_ggc); |
440 gt_ggc_mx (&summary->m_map); | 525 gt_ggc_mx (&summary->m_map); |
441 } | 526 } |