pr88074.c: Require c99_runtime.
[official-gcc.git] / gcc / symbol-summary.h
blob0219f3a81eac56bea237b10f4ed8effe5fe0653b
1 /* Callgraph summary data structure.
2 Copyright (C) 2014-2019 Free Software Foundation, Inc.
3 Contributed by Martin Liska
5 This file is part of GCC.
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.
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.
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/>. */
21 #ifndef GCC_SYMBOL_SUMMARY_H
22 #define GCC_SYMBOL_SUMMARY_H
24 /* Base class for function_summary and fast_function_summary classes. */
26 template <class T>
27 class function_summary_base
29 public:
30 /* Default construction takes SYMTAB as an argument. */
31 function_summary_base (symbol_table *symtab): m_symtab (symtab),
32 m_insertion_enabled (true), m_released (false)
35 /* Basic implementation of insert operation. */
36 virtual void insert (cgraph_node *, T *) {}
38 /* Basic implementation of removal operation. */
39 virtual void remove (cgraph_node *, T *) {}
41 /* Basic implementation of duplication operation. */
42 virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {}
44 /* Enable insertion hook invocation. */
45 void enable_insertion_hook ()
47 m_insertion_enabled = true;
50 /* Enable insertion hook invocation. */
51 void disable_insertion_hook ()
53 m_insertion_enabled = false;
56 protected:
57 /* Allocates new data that are stored within map. */
58 T* allocate_new ()
60 /* Call gcc_internal_because we do not want to call finalizer for
61 a type T. We call dtor explicitly. */
62 return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T () : new T () ;
65 /* Release an item that is stored within map. */
66 void release (T *item)
68 if (is_ggc ())
70 item->~T ();
71 ggc_free (item);
73 else
74 delete item;
77 /* Unregister all call-graph hooks. */
78 void unregister_hooks ();
80 /* Internal summary insertion hook pointer. */
81 cgraph_node_hook_list *m_symtab_insertion_hook;
82 /* Internal summary removal hook pointer. */
83 cgraph_node_hook_list *m_symtab_removal_hook;
84 /* Internal summary duplication hook pointer. */
85 cgraph_2node_hook_list *m_symtab_duplication_hook;
86 /* Symbol table the summary is registered to. */
87 symbol_table *m_symtab;
89 /* Indicates if insertion hook is enabled. */
90 bool m_insertion_enabled;
91 /* Indicates if the summary is released. */
92 bool m_released;
94 private:
95 /* Return true when the summary uses GGC memory for allocation. */
96 virtual bool is_ggc () = 0;
99 template <typename T>
100 void
101 function_summary_base<T>::unregister_hooks ()
103 m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
104 m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
105 m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
108 /* We want to pass just pointer types as argument for function_summary
109 template class. */
111 template <class T>
112 class function_summary
114 private:
115 function_summary();
118 /* Function summary is a helper class that is used to associate a data structure
119 related to a callgraph node. Typical usage can be seen in IPA passes which
120 create a temporary pass-related structures. The summary class registers
121 hooks that are triggered when a new node is inserted, duplicated and deleted.
122 A user of a summary class can ovewrite virtual methods than are triggered by
123 the summary if such hook is triggered. Apart from a callgraph node, the user
124 is given a data structure tied to the node.
126 The function summary class can work both with a heap-allocated memory and
127 a memory gained by garbage collected memory. */
129 template <class T>
130 class GTY((user)) function_summary <T *>: public function_summary_base<T>
132 public:
133 /* Default construction takes SYMTAB as an argument. */
134 function_summary (symbol_table *symtab, bool ggc = false);
136 /* Destructor. */
137 virtual ~function_summary ()
139 release ();
142 /* Destruction method that can be called for GGC purpose. */
143 using function_summary_base<T>::release;
144 void release ();
146 /* Traverses all summarys with a function F called with
147 ARG as argument. */
148 template<typename Arg, bool (*f)(const T &, Arg)>
149 void traverse (Arg a) const
151 m_map.traverse <f> (a);
154 /* Getter for summary callgraph node pointer. If a summary for a node
155 does not exist it will be created. */
156 T* get_create (cgraph_node *node)
158 bool existed;
159 T **v = &m_map.get_or_insert (node->get_uid (), &existed);
160 if (!existed)
161 *v = this->allocate_new ();
163 return *v;
166 /* Getter for summary callgraph node pointer. */
167 T* get (cgraph_node *node) ATTRIBUTE_PURE
169 T **v = m_map.get (node->get_uid ());
170 return v == NULL ? NULL : *v;
173 /* Remove node from summary. */
174 using function_summary_base<T>::remove;
175 void remove (cgraph_node *node)
177 int uid = node->get_uid ();
178 T **v = m_map.get (uid);
179 if (v)
181 m_map.remove (uid);
182 this->release (*v);
186 /* Return true if a summary for the given NODE already exists. */
187 bool exists (cgraph_node *node)
189 return m_map.get (node->get_uid ()) != NULL;
192 /* Symbol insertion hook that is registered to symbol table. */
193 static void symtab_insertion (cgraph_node *node, void *data);
195 /* Symbol removal hook that is registered to symbol table. */
196 static void symtab_removal (cgraph_node *node, void *data);
198 /* Symbol duplication hook that is registered to symbol table. */
199 static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
200 void *data);
202 protected:
203 /* Indication if we use ggc summary. */
204 bool m_ggc;
206 private:
207 /* Indication if we use ggc summary. */
208 virtual bool is_ggc ()
210 return m_ggc;
213 typedef int_hash <int, 0, -1> map_hash;
215 /* Main summary store, where summary ID is used as key. */
216 hash_map <map_hash, T *> m_map;
218 template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &);
219 template <typename U> friend void gt_pch_nx (function_summary <U *> * const &);
220 template <typename U> friend void gt_pch_nx (function_summary <U *> * const &,
221 gt_pointer_operator, void *);
224 template <typename T>
225 function_summary<T *>::function_summary (symbol_table *symtab, bool ggc):
226 function_summary_base<T> (symtab), m_ggc (ggc), m_map (13, ggc)
228 this->m_symtab_insertion_hook
229 = this->m_symtab->add_cgraph_insertion_hook (function_summary::symtab_insertion,
230 this);
231 this->m_symtab_removal_hook
232 = this->m_symtab->add_cgraph_removal_hook (function_summary::symtab_removal,
233 this);
234 this->m_symtab_duplication_hook
235 = this->m_symtab->add_cgraph_duplication_hook (function_summary::symtab_duplication,
236 this);
239 template <typename T>
240 void
241 function_summary<T *>::release ()
243 if (this->m_released)
244 return;
246 this->unregister_hooks ();
248 /* Release all summaries. */
249 typedef typename hash_map <map_hash, T *>::iterator map_iterator;
250 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
251 this->release ((*it).second);
253 this->m_released = true;
256 template <typename T>
257 void
258 function_summary<T *>::symtab_insertion (cgraph_node *node, void *data)
260 gcc_checking_assert (node->get_uid ());
261 function_summary *summary = (function_summary <T *> *) (data);
263 if (summary->m_insertion_enabled)
264 summary->insert (node, summary->get_create (node));
267 template <typename T>
268 void
269 function_summary<T *>::symtab_removal (cgraph_node *node, void *data)
271 gcc_checking_assert (node->get_uid ());
272 function_summary *summary = (function_summary <T *> *) (data);
273 summary->remove (node);
276 template <typename T>
277 void
278 function_summary<T *>::symtab_duplication (cgraph_node *node,
279 cgraph_node *node2, void *data)
281 function_summary *summary = (function_summary <T *> *) (data);
282 T *v = summary->get (node);
284 if (v)
285 summary->duplicate (node, node2, v, summary->get_create (node2));
288 template <typename T>
289 void
290 gt_ggc_mx(function_summary<T *>* const &summary)
292 gcc_checking_assert (summary->m_ggc);
293 gt_ggc_mx (&summary->m_map);
296 template <typename T>
297 void
298 gt_pch_nx(function_summary<T *>* const &summary)
300 gcc_checking_assert (summary->m_ggc);
301 gt_pch_nx (&summary->m_map);
304 template <typename T>
305 void
306 gt_pch_nx(function_summary<T *>* const& summary, gt_pointer_operator op,
307 void *cookie)
309 gcc_checking_assert (summary->m_ggc);
310 gt_pch_nx (&summary->m_map, op, cookie);
313 /* Help template from std c++11. */
315 template<typename T, typename U>
316 struct is_same
318 static const bool value = false;
321 template<typename T>
322 struct is_same<T,T> //specialization
324 static const bool value = true;
327 /* We want to pass just pointer types as argument for fast_function_summary
328 template class. */
330 template <class T, class V>
331 class fast_function_summary
333 private:
334 fast_function_summary ();
337 /* Function vector summary is a fast implementation of function_summary that
338 utilizes vector as primary storage of summaries. */
340 template <class T, class V>
341 class GTY((user)) fast_function_summary <T *, V>
342 : public function_summary_base<T>
344 public:
345 /* Default construction takes SYMTAB as an argument. */
346 fast_function_summary (symbol_table *symtab);
348 /* Destructor. */
349 virtual ~fast_function_summary ()
351 release ();
354 /* Destruction method that can be called for GGC purpose. */
355 using function_summary_base<T>::release;
356 void release ();
358 /* Traverses all summarys with a function F called with
359 ARG as argument. */
360 template<typename Arg, bool (*f)(const T &, Arg)>
361 void traverse (Arg a) const
363 for (unsigned i = 0; i < m_vector->length (); i++)
364 if ((*m_vector[i]) != NULL)
365 f ((*m_vector)[i]);
368 /* Getter for summary callgraph node pointer. If a summary for a node
369 does not exist it will be created. */
370 T* get_create (cgraph_node *node)
372 int id = node->get_summary_id ();
373 if (id == -1)
374 id = this->m_symtab->assign_summary_id (node);
376 if ((unsigned int)id >= m_vector->length ())
377 vec_safe_grow_cleared (m_vector,
378 this->m_symtab->cgraph_max_summary_id);
380 if ((*m_vector)[id] == NULL)
381 (*m_vector)[id] = this->allocate_new ();
383 return (*m_vector)[id];
386 /* Getter for summary callgraph node pointer. */
387 T* get (cgraph_node *node) ATTRIBUTE_PURE
389 return exists (node) ? (*m_vector)[node->get_summary_id ()] : NULL;
392 using function_summary_base<T>::remove;
393 void remove (cgraph_node *node)
395 if (exists (node))
397 int id = node->get_summary_id ();
398 this->release ((*m_vector)[id]);
399 (*m_vector)[id] = NULL;
403 /* Return true if a summary for the given NODE already exists. */
404 bool exists (cgraph_node *node)
406 int id = node->get_summary_id ();
407 return (id != -1
408 && (unsigned int)id < m_vector->length ()
409 && (*m_vector)[id] != NULL);
412 /* Symbol insertion hook that is registered to symbol table. */
413 static void symtab_insertion (cgraph_node *node, void *data);
415 /* Symbol removal hook that is registered to symbol table. */
416 static void symtab_removal (cgraph_node *node, void *data);
418 /* Symbol duplication hook that is registered to symbol table. */
419 static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
420 void *data);
422 private:
423 virtual bool is_ggc ();
425 /* Summary is stored in the vector. */
426 vec <T *, V> *m_vector;
428 template <typename U> friend void gt_ggc_mx (fast_function_summary <U *, va_gc> * const &);
429 template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &);
430 template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &,
431 gt_pointer_operator, void *);
434 template <typename T, typename V>
435 fast_function_summary<T *, V>::fast_function_summary (symbol_table *symtab):
436 function_summary_base<T> (symtab), m_vector (NULL)
438 vec_alloc (m_vector, 13);
439 this->m_symtab_insertion_hook
440 = this->m_symtab->add_cgraph_insertion_hook (fast_function_summary::symtab_insertion,
441 this);
442 this->m_symtab_removal_hook
443 = this->m_symtab->add_cgraph_removal_hook (fast_function_summary::symtab_removal,
444 this);
445 this->m_symtab_duplication_hook
446 = this->m_symtab->add_cgraph_duplication_hook (fast_function_summary::symtab_duplication,
447 this);
450 template <typename T, typename V>
451 void
452 fast_function_summary<T *, V>::release ()
454 if (this->m_released)
455 return;
457 this->unregister_hooks ();
459 /* Release all summaries. */
460 for (unsigned i = 0; i < m_vector->length (); i++)
461 if ((*m_vector)[i] != NULL)
462 this->release ((*m_vector)[i]);
464 this->m_released = true;
467 template <typename T, typename V>
468 void
469 fast_function_summary<T *, V>::symtab_insertion (cgraph_node *node, void *data)
471 gcc_checking_assert (node->get_uid ());
472 fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
474 if (summary->m_insertion_enabled)
475 summary->insert (node, summary->get_create (node));
478 template <typename T, typename V>
479 void
480 fast_function_summary<T *, V>::symtab_removal (cgraph_node *node, void *data)
482 gcc_checking_assert (node->get_uid ());
483 fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
485 if (summary->exists (node))
486 summary->remove (node);
489 template <typename T, typename V>
490 void
491 fast_function_summary<T *, V>::symtab_duplication (cgraph_node *node,
492 cgraph_node *node2,
493 void *data)
495 fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
496 T *v = summary->get (node);
498 if (v)
500 T *duplicate = summary->get_create (node2);
501 summary->duplicate (node, node2, v, duplicate);
505 template <typename T, typename V>
506 inline bool
507 fast_function_summary<T *, V>::is_ggc ()
509 return is_same<V, va_gc>::value;
512 template <typename T>
513 void
514 gt_ggc_mx (fast_function_summary<T *, va_heap>* const &)
518 template <typename T>
519 void
520 gt_pch_nx (fast_function_summary<T *, va_heap>* const &)
524 template <typename T>
525 void
526 gt_pch_nx (fast_function_summary<T *, va_heap>* const&, gt_pointer_operator,
527 void *)
531 template <typename T>
532 void
533 gt_ggc_mx (fast_function_summary<T *, va_gc>* const &summary)
535 ggc_test_and_set_mark (summary->m_vector);
536 gt_ggc_mx (summary->m_vector);
539 template <typename T>
540 void
541 gt_pch_nx (fast_function_summary<T *, va_gc>* const &summary)
543 gt_pch_nx (summary->m_vector);
546 template <typename T>
547 void
548 gt_pch_nx (fast_function_summary<T *, va_gc>* const& summary,
549 gt_pointer_operator op,
550 void *cookie)
552 gt_pch_nx (summary->m_vector, op, cookie);
555 /* Base class for call_summary and fast_call_summary classes. */
557 template <class T>
558 class call_summary_base
560 public:
561 /* Default construction takes SYMTAB as an argument. */
562 call_summary_base (symbol_table *symtab): m_symtab (symtab),
563 m_initialize_when_cloning (true), m_released (false)
566 /* Basic implementation of removal operation. */
567 virtual void remove (cgraph_edge *, T *) {}
569 /* Basic implementation of duplication operation. */
570 virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *) {}
572 protected:
573 /* Allocates new data that are stored within map. */
574 T* allocate_new ()
576 /* Call gcc_internal_because we do not want to call finalizer for
577 a type T. We call dtor explicitly. */
578 return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T () : new T () ;
581 /* Release an item that is stored within map. */
582 void release (T *item)
584 if (is_ggc ())
586 item->~T ();
587 ggc_free (item);
589 else
590 delete item;
593 /* Unregister all call-graph hooks. */
594 void unregister_hooks ();
596 /* Symbol table the summary is registered to. */
597 symbol_table *m_symtab;
599 /* Internal summary removal hook pointer. */
600 cgraph_edge_hook_list *m_symtab_removal_hook;
601 /* Internal summary duplication hook pointer. */
602 cgraph_2edge_hook_list *m_symtab_duplication_hook;
603 /* Initialize summary for an edge that is cloned. */
604 bool m_initialize_when_cloning;
605 /* Indicates if the summary is released. */
606 bool m_released;
608 private:
609 /* Return true when the summary uses GGC memory for allocation. */
610 virtual bool is_ggc () = 0;
613 template <typename T>
614 void
615 call_summary_base<T>::unregister_hooks ()
617 m_symtab->remove_edge_removal_hook (m_symtab_removal_hook);
618 m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook);
621 /* An impossible class templated by non-pointers so, which makes sure that only
622 summaries gathering pointers can be created. */
624 template <class T>
625 class call_summary
627 private:
628 call_summary ();
631 /* Class to store auxiliary information about call graph edges. */
633 template <class T>
634 class GTY((user)) call_summary <T *>: public call_summary_base<T>
636 public:
637 /* Default construction takes SYMTAB as an argument. */
638 call_summary (symbol_table *symtab, bool ggc = false)
639 : call_summary_base<T> (symtab), m_ggc (ggc), m_map (13, ggc)
641 this->m_symtab_removal_hook
642 = this->m_symtab->add_edge_removal_hook (call_summary::symtab_removal,
643 this);
644 this->m_symtab_duplication_hook
645 = this->m_symtab->add_edge_duplication_hook (call_summary::symtab_duplication,
646 this);
649 /* Destructor. */
650 virtual ~call_summary ()
652 release ();
655 /* Destruction method that can be called for GGC purpose. */
656 using call_summary_base<T>::release;
657 void release ();
659 /* Traverses all summarys with an edge E called with
660 ARG as argument. */
661 template<typename Arg, bool (*f)(const T &, Arg)>
662 void traverse (Arg a) const
664 m_map.traverse <f> (a);
667 /* Getter for summary callgraph edge pointer.
668 If a summary for an edge does not exist, it will be created. */
669 T* get_create (cgraph_edge *edge)
671 bool existed;
672 T **v = &m_map.get_or_insert (edge->get_uid (), &existed);
673 if (!existed)
674 *v = this->allocate_new ();
676 return *v;
679 /* Getter for summary callgraph edge pointer. */
680 T* get (cgraph_edge *edge) ATTRIBUTE_PURE
682 T **v = m_map.get (edge->get_uid ());
683 return v == NULL ? NULL : *v;
686 /* Remove edge from summary. */
687 using call_summary_base<T>::remove;
688 void remove (cgraph_edge *edge)
690 int uid = edge->get_uid ();
691 T **v = m_map.get (uid);
692 if (v)
694 m_map.remove (uid);
695 this->release (*v);
699 /* Return true if a summary for the given EDGE already exists. */
700 bool exists (cgraph_edge *edge)
702 return m_map.get (edge->get_uid ()) != NULL;
705 /* Symbol removal hook that is registered to symbol table. */
706 static void symtab_removal (cgraph_edge *edge, void *data);
708 /* Symbol duplication hook that is registered to symbol table. */
709 static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
710 void *data);
712 protected:
713 /* Indication if we use ggc summary. */
714 bool m_ggc;
716 private:
717 /* Indication if we use ggc summary. */
718 virtual bool is_ggc ()
720 return m_ggc;
723 typedef int_hash <int, 0, -1> map_hash;
725 /* Main summary store, where summary ID is used as key. */
726 hash_map <map_hash, T *> m_map;
728 template <typename U> friend void gt_ggc_mx (call_summary <U *> * const &);
729 template <typename U> friend void gt_pch_nx (call_summary <U *> * const &);
730 template <typename U> friend void gt_pch_nx (call_summary <U *> * const &,
731 gt_pointer_operator, void *);
734 template <typename T>
735 void
736 call_summary<T *>::release ()
738 if (this->m_released)
739 return;
741 this->unregister_hooks ();
743 /* Release all summaries. */
744 typedef typename hash_map <map_hash, T *>::iterator map_iterator;
745 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
746 this->release ((*it).second);
748 this->m_released = true;
751 template <typename T>
752 void
753 call_summary<T *>::symtab_removal (cgraph_edge *edge, void *data)
755 call_summary *summary = (call_summary <T *> *) (data);
756 summary->remove (edge);
759 template <typename T>
760 void
761 call_summary<T *>::symtab_duplication (cgraph_edge *edge1,
762 cgraph_edge *edge2, void *data)
764 call_summary *summary = (call_summary <T *> *) (data);
765 T *edge1_summary = NULL;
767 if (summary->m_initialize_when_cloning)
768 edge1_summary = summary->get_create (edge1);
769 else
770 edge1_summary = summary->get (edge1);
772 if (edge1_summary)
773 summary->duplicate (edge1, edge2, edge1_summary,
774 summary->get_create (edge2));
777 template <typename T>
778 void
779 gt_ggc_mx(call_summary<T *>* const &summary)
781 gcc_checking_assert (summary->m_ggc);
782 gt_ggc_mx (&summary->m_map);
785 template <typename T>
786 void
787 gt_pch_nx(call_summary<T *>* const &summary)
789 gcc_checking_assert (summary->m_ggc);
790 gt_pch_nx (&summary->m_map);
793 template <typename T>
794 void
795 gt_pch_nx(call_summary<T *>* const& summary, gt_pointer_operator op,
796 void *cookie)
798 gcc_checking_assert (summary->m_ggc);
799 gt_pch_nx (&summary->m_map, op, cookie);
802 /* We want to pass just pointer types as argument for fast_call_summary
803 template class. */
805 template <class T, class V>
806 class fast_call_summary
808 private:
809 fast_call_summary ();
812 /* Call vector summary is a fast implementation of call_summary that
813 utilizes vector as primary storage of summaries. */
815 template <class T, class V>
816 class GTY((user)) fast_call_summary <T *, V>: public call_summary_base<T>
818 public:
819 /* Default construction takes SYMTAB as an argument. */
820 fast_call_summary (symbol_table *symtab)
821 : call_summary_base<T> (symtab), m_vector (NULL)
823 vec_alloc (m_vector, 13);
824 this->m_symtab_removal_hook
825 = this->m_symtab->add_edge_removal_hook (fast_call_summary::symtab_removal,
826 this);
827 this->m_symtab_duplication_hook
828 = this->m_symtab->add_edge_duplication_hook (fast_call_summary::symtab_duplication,
829 this);
832 /* Destructor. */
833 virtual ~fast_call_summary ()
835 release ();
838 /* Destruction method that can be called for GGC purpose. */
839 using call_summary_base<T>::release;
840 void release ();
842 /* Traverses all summarys with an edge F called with
843 ARG as argument. */
844 template<typename Arg, bool (*f)(const T &, Arg)>
845 void traverse (Arg a) const
847 for (unsigned i = 0; i < m_vector->length (); i++)
848 if ((*m_vector[i]) != NULL)
849 f ((*m_vector)[i]);
852 /* Getter for summary callgraph edge pointer.
853 If a summary for an edge does not exist, it will be created. */
854 T* get_create (cgraph_edge *edge)
856 int id = edge->get_summary_id ();
857 if (id == -1)
858 id = this->m_symtab->assign_summary_id (edge);
860 if ((unsigned)id >= m_vector->length ())
861 vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id);
863 if ((*m_vector)[id] == NULL)
864 (*m_vector)[id] = this->allocate_new ();
866 return (*m_vector)[id];
869 /* Getter for summary callgraph edge pointer. */
870 T* get (cgraph_edge *edge) ATTRIBUTE_PURE
872 return exists (edge) ? (*m_vector)[edge->get_summary_id ()] : NULL;
875 /* Remove edge from summary. */
876 using call_summary_base<T>::remove;
877 void remove (cgraph_edge *edge)
879 if (exists (edge))
881 int id = edge->get_summary_id ();
882 this->release ((*m_vector)[id]);
883 (*m_vector)[id] = NULL;
887 /* Return true if a summary for the given EDGE already exists. */
888 bool exists (cgraph_edge *edge)
890 int id = edge->get_summary_id ();
891 return (id != -1
892 && (unsigned)id < m_vector->length ()
893 && (*m_vector)[id] != NULL);
896 /* Symbol removal hook that is registered to symbol table. */
897 static void symtab_removal (cgraph_edge *edge, void *data);
899 /* Symbol duplication hook that is registered to symbol table. */
900 static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
901 void *data);
903 private:
904 virtual bool is_ggc ();
906 /* Summary is stored in the vector. */
907 vec <T *, V> *m_vector;
909 template <typename U> friend void gt_ggc_mx (fast_call_summary <U *, va_gc> * const &);
910 template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &);
911 template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &,
912 gt_pointer_operator, void *);
915 template <typename T, typename V>
916 void
917 fast_call_summary<T *, V>::release ()
919 if (this->m_released)
920 return;
922 this->unregister_hooks ();
924 /* Release all summaries. */
925 for (unsigned i = 0; i < m_vector->length (); i++)
926 if ((*m_vector)[i] != NULL)
927 this->release ((*m_vector)[i]);
929 this->m_released = true;
932 template <typename T, typename V>
933 void
934 fast_call_summary<T *, V>::symtab_removal (cgraph_edge *edge, void *data)
936 fast_call_summary *summary = (fast_call_summary <T *, V> *) (data);
937 summary->remove (edge);
940 template <typename T, typename V>
941 void
942 fast_call_summary<T *, V>::symtab_duplication (cgraph_edge *edge1,
943 cgraph_edge *edge2, void *data)
945 fast_call_summary *summary = (fast_call_summary <T *, V> *) (data);
946 T *edge1_summary = NULL;
948 if (summary->m_initialize_when_cloning)
949 edge1_summary = summary->get_create (edge1);
950 else
951 edge1_summary = summary->get (edge1);
953 if (edge1_summary)
955 T *duplicate = summary->get_create (edge2);
956 summary->duplicate (edge1, edge2, edge1_summary, duplicate);
960 template <typename T, typename V>
961 inline bool
962 fast_call_summary<T *, V>::is_ggc ()
964 return is_same<V, va_gc>::value;
967 template <typename T>
968 void
969 gt_ggc_mx (fast_call_summary<T *, va_heap>* const &summary)
973 template <typename T>
974 void
975 gt_pch_nx (fast_call_summary<T *, va_heap>* const &summary)
979 template <typename T>
980 void
981 gt_pch_nx (fast_call_summary<T *, va_heap>* const& summary,
982 gt_pointer_operator op,
983 void *cookie)
987 template <typename T>
988 void
989 gt_ggc_mx (fast_call_summary<T *, va_gc>* const &summary)
991 ggc_test_and_set_mark (summary->m_vector);
992 gt_ggc_mx (&summary->m_vector);
995 template <typename T>
996 void
997 gt_pch_nx (fast_call_summary<T *, va_gc>* const &summary)
999 gt_pch_nx (&summary->m_vector);
1002 template <typename T>
1003 void
1004 gt_pch_nx (fast_call_summary<T *, va_gc>* const& summary,
1005 gt_pointer_operator op,
1006 void *cookie)
1008 gt_pch_nx (&summary->m_vector, op, cookie);
1011 #endif /* GCC_SYMBOL_SUMMARY_H */