Daily bump.
[official-gcc.git] / gcc / symbol-summary.h
blobfa1df5c8015698787c9593d263d1cae1bd53e2ba
1 /* Callgraph summary data structure.
2 Copyright (C) 2014-2020 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 CXX_MEM_STAT_INFO):
32 m_symtab (symtab),
33 m_insertion_enabled (true),
34 m_allocator ("function summary" PASS_MEM_STAT)
37 /* Basic implementation of insert operation. */
38 virtual void insert (cgraph_node *, T *) {}
40 /* Basic implementation of removal operation. */
41 virtual void remove (cgraph_node *, T *) {}
43 /* Basic implementation of duplication operation. */
44 virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {}
46 /* Enable insertion hook invocation. */
47 void enable_insertion_hook ()
49 m_insertion_enabled = true;
52 /* Enable insertion hook invocation. */
53 void disable_insertion_hook ()
55 m_insertion_enabled = false;
58 protected:
59 /* Allocates new data that are stored within map. */
60 T* allocate_new ()
62 /* Call gcc_internal_because we do not want to call finalizer for
63 a type T. We call dtor explicitly. */
64 return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
65 : m_allocator.allocate () ;
68 /* Release an item that is stored within map. */
69 void release (T *item)
71 if (is_ggc ())
72 ggc_delete (item);
73 else
74 m_allocator.remove (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;
92 private:
93 /* Return true when the summary uses GGC memory for allocation. */
94 virtual bool is_ggc () = 0;
96 /* Object allocator for heap allocation. */
97 object_allocator<T> m_allocator;
100 template <typename T>
101 void
102 function_summary_base<T>::unregister_hooks ()
104 m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
105 m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
106 m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
109 /* We want to pass just pointer types as argument for function_summary
110 template class. */
112 template <class T>
113 class function_summary
115 private:
116 function_summary();
119 /* Function summary is a helper class that is used to associate a data structure
120 related to a callgraph node. Typical usage can be seen in IPA passes which
121 create a temporary pass-related structures. The summary class registers
122 hooks that are triggered when a new node is inserted, duplicated and deleted.
123 A user of a summary class can ovewrite virtual methods than are triggered by
124 the summary if such hook is triggered. Apart from a callgraph node, the user
125 is given a data structure tied to the node.
127 The function summary class can work both with a heap-allocated memory and
128 a memory gained by garbage collected memory. */
130 template <class T>
131 class GTY((user)) function_summary <T *>: public function_summary_base<T>
133 public:
134 /* Default construction takes SYMTAB as an argument. */
135 function_summary (symbol_table *symtab, bool ggc = false CXX_MEM_STAT_INFO);
137 /* Destructor. */
138 virtual ~function_summary ();
140 /* Traverses all summarys with a function F called with
141 ARG as argument. */
142 template<typename Arg, bool (*f)(const T &, Arg)>
143 void traverse (Arg a) const
145 m_map.traverse <f> (a);
148 /* Getter for summary callgraph node pointer. If a summary for a node
149 does not exist it will be created. */
150 T* get_create (cgraph_node *node)
152 bool existed;
153 T **v = &m_map.get_or_insert (node->get_uid (), &existed);
154 if (!existed)
155 *v = this->allocate_new ();
157 return *v;
160 /* Getter for summary callgraph node pointer. */
161 T* get (cgraph_node *node) ATTRIBUTE_PURE
163 T **v = m_map.get (node->get_uid ());
164 return v == NULL ? NULL : *v;
167 /* Remove node from summary. */
168 using function_summary_base<T>::remove;
169 void remove (cgraph_node *node)
171 int uid = node->get_uid ();
172 T **v = m_map.get (uid);
173 if (v)
175 m_map.remove (uid);
176 this->release (*v);
180 /* Return true if a summary for the given NODE already exists. */
181 bool exists (cgraph_node *node)
183 return m_map.get (node->get_uid ()) != NULL;
186 /* Symbol insertion hook that is registered to symbol table. */
187 static void symtab_insertion (cgraph_node *node, void *data);
189 /* Symbol removal hook that is registered to symbol table. */
190 static void symtab_removal (cgraph_node *node, void *data);
192 /* Symbol duplication hook that is registered to symbol table. */
193 static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
194 void *data);
196 protected:
197 /* Indication if we use ggc summary. */
198 bool m_ggc;
200 private:
201 /* Indication if we use ggc summary. */
202 virtual bool is_ggc ()
204 return m_ggc;
207 typedef int_hash <int, 0, -1> map_hash;
209 /* Main summary store, where summary ID is used as key. */
210 hash_map <map_hash, T *> m_map;
212 template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &);
213 template <typename U> friend void gt_pch_nx (function_summary <U *> * const &);
214 template <typename U> friend void gt_pch_nx (function_summary <U *> * const &,
215 gt_pointer_operator, void *);
218 template <typename T>
219 function_summary<T *>::function_summary (symbol_table *symtab, bool ggc
220 MEM_STAT_DECL):
221 function_summary_base<T> (symtab PASS_MEM_STAT), m_ggc (ggc),
222 m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT)
224 this->m_symtab_insertion_hook
225 = this->m_symtab->add_cgraph_insertion_hook (function_summary::symtab_insertion,
226 this);
227 this->m_symtab_removal_hook
228 = this->m_symtab->add_cgraph_removal_hook (function_summary::symtab_removal,
229 this);
230 this->m_symtab_duplication_hook
231 = this->m_symtab->add_cgraph_duplication_hook (function_summary::symtab_duplication,
232 this);
235 template <typename T>
236 function_summary<T *>::~function_summary ()
238 this->unregister_hooks ();
240 /* Release all summaries. */
241 typedef typename hash_map <map_hash, T *>::iterator map_iterator;
242 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
243 this->release ((*it).second);
246 template <typename T>
247 void
248 function_summary<T *>::symtab_insertion (cgraph_node *node, void *data)
250 gcc_checking_assert (node->get_uid ());
251 function_summary *summary = (function_summary <T *> *) (data);
253 if (summary->m_insertion_enabled)
254 summary->insert (node, summary->get_create (node));
257 template <typename T>
258 void
259 function_summary<T *>::symtab_removal (cgraph_node *node, void *data)
261 gcc_checking_assert (node->get_uid ());
262 function_summary *summary = (function_summary <T *> *) (data);
263 summary->remove (node);
266 template <typename T>
267 void
268 function_summary<T *>::symtab_duplication (cgraph_node *node,
269 cgraph_node *node2, void *data)
271 function_summary *summary = (function_summary <T *> *) (data);
272 T *v = summary->get (node);
274 if (v)
275 summary->duplicate (node, node2, v, summary->get_create (node2));
278 template <typename T>
279 void
280 gt_ggc_mx(function_summary<T *>* const &summary)
282 gcc_checking_assert (summary->m_ggc);
283 gt_ggc_mx (&summary->m_map);
286 template <typename T>
287 void
288 gt_pch_nx (function_summary<T *> *const &)
290 gcc_unreachable ();
293 template <typename T>
294 void
295 gt_pch_nx (function_summary<T *> *const &, gt_pointer_operator, void *)
297 gcc_unreachable ();
300 /* Help template from std c++11. */
302 template<typename T, typename U>
303 struct is_same
305 static const bool value = false;
308 template<typename T>
309 struct is_same<T,T> //specialization
311 static const bool value = true;
314 /* We want to pass just pointer types as argument for fast_function_summary
315 template class. */
317 template <class T, class V>
318 class fast_function_summary
320 private:
321 fast_function_summary ();
324 /* Function vector summary is a fast implementation of function_summary that
325 utilizes vector as primary storage of summaries. */
327 template <class T, class V>
328 class GTY((user)) fast_function_summary <T *, V>
329 : public function_summary_base<T>
331 public:
332 /* Default construction takes SYMTAB as an argument. */
333 fast_function_summary (symbol_table *symtab CXX_MEM_STAT_INFO);
335 /* Destructor. */
336 virtual ~fast_function_summary ();
338 /* Traverses all summarys with a function F called with
339 ARG as argument. */
340 template<typename Arg, bool (*f)(const T &, Arg)>
341 void traverse (Arg a) const
343 for (unsigned i = 0; i < m_vector->length (); i++)
344 if ((*m_vector[i]) != NULL)
345 f ((*m_vector)[i], a);
348 /* Getter for summary callgraph node pointer. If a summary for a node
349 does not exist it will be created. */
350 T* get_create (cgraph_node *node)
352 int id = node->get_summary_id ();
353 if (id == -1)
354 id = this->m_symtab->assign_summary_id (node);
356 if ((unsigned int)id >= m_vector->length ())
358 int newlen = this->m_symtab->cgraph_max_summary_id;
359 vec_safe_reserve (m_vector, newlen - m_vector->length ());
360 m_vector->quick_grow_cleared (newlen);
363 if ((*m_vector)[id] == NULL)
364 (*m_vector)[id] = this->allocate_new ();
366 return (*m_vector)[id];
369 /* Getter for summary callgraph node pointer. */
370 T* get (cgraph_node *node) ATTRIBUTE_PURE
372 return exists (node) ? (*m_vector)[node->get_summary_id ()] : NULL;
375 using function_summary_base<T>::remove;
376 void remove (cgraph_node *node)
378 if (exists (node))
380 int id = node->get_summary_id ();
381 this->release ((*m_vector)[id]);
382 (*m_vector)[id] = NULL;
386 /* Return true if a summary for the given NODE already exists. */
387 bool exists (cgraph_node *node)
389 int id = node->get_summary_id ();
390 return (id != -1
391 && (unsigned int)id < m_vector->length ()
392 && (*m_vector)[id] != NULL);
395 /* Symbol insertion hook that is registered to symbol table. */
396 static void symtab_insertion (cgraph_node *node, void *data);
398 /* Symbol removal hook that is registered to symbol table. */
399 static void symtab_removal (cgraph_node *node, void *data);
401 /* Symbol duplication hook that is registered to symbol table. */
402 static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
403 void *data);
405 private:
406 virtual bool is_ggc ();
408 /* Summary is stored in the vector. */
409 vec <T *, V> *m_vector;
411 template <typename U> friend void gt_ggc_mx (fast_function_summary <U *, va_gc> * const &);
412 template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &);
413 template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &,
414 gt_pointer_operator, void *);
417 template <typename T, typename V>
418 fast_function_summary<T *, V>::fast_function_summary (symbol_table *symtab MEM_STAT_DECL):
419 function_summary_base<T> (symtab PASS_MEM_STAT), m_vector (NULL)
421 vec_alloc (m_vector, 13 PASS_MEM_STAT);
422 this->m_symtab_insertion_hook
423 = this->m_symtab->add_cgraph_insertion_hook (fast_function_summary::symtab_insertion,
424 this);
425 this->m_symtab_removal_hook
426 = this->m_symtab->add_cgraph_removal_hook (fast_function_summary::symtab_removal,
427 this);
428 this->m_symtab_duplication_hook
429 = this->m_symtab->add_cgraph_duplication_hook (fast_function_summary::symtab_duplication,
430 this);
433 template <typename T, typename V>
434 fast_function_summary<T *, V>::~fast_function_summary ()
436 this->unregister_hooks ();
438 /* Release all summaries. */
439 for (unsigned i = 0; i < m_vector->length (); i++)
440 if ((*m_vector)[i] != NULL)
441 this->release ((*m_vector)[i]);
442 vec_free (m_vector);
445 template <typename T, typename V>
446 void
447 fast_function_summary<T *, V>::symtab_insertion (cgraph_node *node, void *data)
449 gcc_checking_assert (node->get_uid ());
450 fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
452 if (summary->m_insertion_enabled)
453 summary->insert (node, summary->get_create (node));
456 template <typename T, typename V>
457 void
458 fast_function_summary<T *, V>::symtab_removal (cgraph_node *node, void *data)
460 gcc_checking_assert (node->get_uid ());
461 fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
463 if (summary->exists (node))
464 summary->remove (node);
467 template <typename T, typename V>
468 void
469 fast_function_summary<T *, V>::symtab_duplication (cgraph_node *node,
470 cgraph_node *node2,
471 void *data)
473 fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
474 T *v = summary->get (node);
476 if (v)
478 T *duplicate = summary->get_create (node2);
479 summary->duplicate (node, node2, v, duplicate);
483 template <typename T, typename V>
484 inline bool
485 fast_function_summary<T *, V>::is_ggc ()
487 return is_same<V, va_gc>::value;
490 template <typename T>
491 void
492 gt_ggc_mx (fast_function_summary<T *, va_heap>* const &)
496 template <typename T>
497 void
498 gt_pch_nx (fast_function_summary<T *, va_heap>* const &)
502 template <typename T>
503 void
504 gt_pch_nx (fast_function_summary<T *, va_heap>* const&, gt_pointer_operator,
505 void *)
509 template <typename T>
510 void
511 gt_ggc_mx (fast_function_summary<T *, va_gc>* const &summary)
513 ggc_test_and_set_mark (summary->m_vector);
514 gt_ggc_mx (summary->m_vector);
517 template <typename T>
518 void
519 gt_pch_nx (fast_function_summary<T *, va_gc> *const &)
521 gcc_unreachable ();
524 template <typename T>
525 void
526 gt_pch_nx (fast_function_summary<T *, va_gc> *const &, gt_pointer_operator,
527 void *)
529 gcc_unreachable ();
532 /* Base class for call_summary and fast_call_summary classes. */
534 template <class T>
535 class call_summary_base
537 public:
538 /* Default construction takes SYMTAB as an argument. */
539 call_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO):
540 m_symtab (symtab),
541 m_initialize_when_cloning (false),
542 m_allocator ("call summary" PASS_MEM_STAT)
545 /* Basic implementation of removal operation. */
546 virtual void remove (cgraph_edge *, T *) {}
548 /* Basic implementation of duplication operation. */
549 virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *) {}
551 protected:
552 /* Allocates new data that are stored within map. */
553 T* allocate_new ()
555 /* Call gcc_internal_because we do not want to call finalizer for
556 a type T. We call dtor explicitly. */
557 return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
558 : m_allocator.allocate ();
561 /* Release an item that is stored within map. */
562 void release (T *item)
564 if (is_ggc ())
565 ggc_delete (item);
566 else
567 m_allocator.remove (item);
570 /* Unregister all call-graph hooks. */
571 void unregister_hooks ();
573 /* Symbol table the summary is registered to. */
574 symbol_table *m_symtab;
576 /* Internal summary removal hook pointer. */
577 cgraph_edge_hook_list *m_symtab_removal_hook;
578 /* Internal summary duplication hook pointer. */
579 cgraph_2edge_hook_list *m_symtab_duplication_hook;
580 /* Initialize summary for an edge that is cloned. */
581 bool m_initialize_when_cloning;
583 private:
584 /* Return true when the summary uses GGC memory for allocation. */
585 virtual bool is_ggc () = 0;
587 /* Object allocator for heap allocation. */
588 object_allocator<T> m_allocator;
591 template <typename T>
592 void
593 call_summary_base<T>::unregister_hooks ()
595 m_symtab->remove_edge_removal_hook (m_symtab_removal_hook);
596 m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook);
599 /* An impossible class templated by non-pointers so, which makes sure that only
600 summaries gathering pointers can be created. */
602 template <class T>
603 class call_summary
605 private:
606 call_summary ();
609 /* Class to store auxiliary information about call graph edges. */
611 template <class T>
612 class GTY((user)) call_summary <T *>: public call_summary_base<T>
614 public:
615 /* Default construction takes SYMTAB as an argument. */
616 call_summary (symbol_table *symtab, bool ggc = false
617 CXX_MEM_STAT_INFO)
618 : call_summary_base<T> (symtab PASS_MEM_STAT), m_ggc (ggc),
619 m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT)
621 this->m_symtab_removal_hook
622 = this->m_symtab->add_edge_removal_hook (call_summary::symtab_removal,
623 this);
624 this->m_symtab_duplication_hook
625 = this->m_symtab->add_edge_duplication_hook (call_summary::symtab_duplication,
626 this);
629 /* Destructor. */
630 virtual ~call_summary ();
632 /* Traverses all summarys with an edge E called with
633 ARG as argument. */
634 template<typename Arg, bool (*f)(const T &, Arg)>
635 void traverse (Arg a) const
637 m_map.traverse <f> (a);
640 /* Getter for summary callgraph edge pointer.
641 If a summary for an edge does not exist, it will be created. */
642 T* get_create (cgraph_edge *edge)
644 bool existed;
645 T **v = &m_map.get_or_insert (edge->get_uid (), &existed);
646 if (!existed)
647 *v = this->allocate_new ();
649 return *v;
652 /* Getter for summary callgraph edge pointer. */
653 T* get (cgraph_edge *edge) ATTRIBUTE_PURE
655 T **v = m_map.get (edge->get_uid ());
656 return v == NULL ? NULL : *v;
659 /* Remove edge from summary. */
660 using call_summary_base<T>::remove;
661 void remove (cgraph_edge *edge)
663 int uid = edge->get_uid ();
664 T **v = m_map.get (uid);
665 if (v)
667 m_map.remove (uid);
668 this->release (*v);
672 /* Return true if a summary for the given EDGE already exists. */
673 bool exists (cgraph_edge *edge)
675 return m_map.get (edge->get_uid ()) != NULL;
678 /* Symbol removal hook that is registered to symbol table. */
679 static void symtab_removal (cgraph_edge *edge, void *data);
681 /* Symbol duplication hook that is registered to symbol table. */
682 static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
683 void *data);
685 protected:
686 /* Indication if we use ggc summary. */
687 bool m_ggc;
689 private:
690 /* Indication if we use ggc summary. */
691 virtual bool is_ggc ()
693 return m_ggc;
696 typedef int_hash <int, 0, -1> map_hash;
698 /* Main summary store, where summary ID is used as key. */
699 hash_map <map_hash, T *> m_map;
701 template <typename U> friend void gt_ggc_mx (call_summary <U *> * const &);
702 template <typename U> friend void gt_pch_nx (call_summary <U *> * const &);
703 template <typename U> friend void gt_pch_nx (call_summary <U *> * const &,
704 gt_pointer_operator, void *);
707 template <typename T>
708 call_summary<T *>::~call_summary ()
710 this->unregister_hooks ();
712 /* Release all summaries. */
713 typedef typename hash_map <map_hash, T *>::iterator map_iterator;
714 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
715 this->release ((*it).second);
718 template <typename T>
719 void
720 call_summary<T *>::symtab_removal (cgraph_edge *edge, void *data)
722 call_summary *summary = (call_summary <T *> *) (data);
723 summary->remove (edge);
726 template <typename T>
727 void
728 call_summary<T *>::symtab_duplication (cgraph_edge *edge1,
729 cgraph_edge *edge2, void *data)
731 call_summary *summary = (call_summary <T *> *) (data);
732 T *edge1_summary = NULL;
734 if (summary->m_initialize_when_cloning)
735 edge1_summary = summary->get_create (edge1);
736 else
737 edge1_summary = summary->get (edge1);
739 if (edge1_summary)
740 summary->duplicate (edge1, edge2, edge1_summary,
741 summary->get_create (edge2));
744 template <typename T>
745 void
746 gt_ggc_mx(call_summary<T *>* const &summary)
748 gcc_checking_assert (summary->m_ggc);
749 gt_ggc_mx (&summary->m_map);
752 template <typename T>
753 void
754 gt_pch_nx (call_summary<T *> *const &)
756 gcc_unreachable ();
759 template <typename T>
760 void
761 gt_pch_nx (call_summary<T *> *const &, gt_pointer_operator, void *)
763 gcc_unreachable ();
766 /* We want to pass just pointer types as argument for fast_call_summary
767 template class. */
769 template <class T, class V>
770 class fast_call_summary
772 private:
773 fast_call_summary ();
776 /* Call vector summary is a fast implementation of call_summary that
777 utilizes vector as primary storage of summaries. */
779 template <class T, class V>
780 class GTY((user)) fast_call_summary <T *, V>: public call_summary_base<T>
782 public:
783 /* Default construction takes SYMTAB as an argument. */
784 fast_call_summary (symbol_table *symtab CXX_MEM_STAT_INFO)
785 : call_summary_base<T> (symtab PASS_MEM_STAT), m_vector (NULL)
787 vec_alloc (m_vector, 13 PASS_MEM_STAT);
788 this->m_symtab_removal_hook
789 = this->m_symtab->add_edge_removal_hook (fast_call_summary::symtab_removal,
790 this);
791 this->m_symtab_duplication_hook
792 = this->m_symtab->add_edge_duplication_hook (fast_call_summary::symtab_duplication,
793 this);
796 /* Destructor. */
797 virtual ~fast_call_summary ();
799 /* Traverses all summarys with an edge F called with
800 ARG as argument. */
801 template<typename Arg, bool (*f)(const T &, Arg)>
802 void traverse (Arg a) const
804 for (unsigned i = 0; i < m_vector->length (); i++)
805 if ((*m_vector[i]) != NULL)
806 f ((*m_vector)[i], a);
809 /* Getter for summary callgraph edge pointer.
810 If a summary for an edge does not exist, it will be created. */
811 T* get_create (cgraph_edge *edge)
813 int id = edge->get_summary_id ();
814 if (id == -1)
815 id = this->m_symtab->assign_summary_id (edge);
817 if ((unsigned)id >= m_vector->length ())
819 int newlen = this->m_symtab->edges_max_summary_id;
820 m_vector->reserve (newlen - m_vector->length ());
821 m_vector->quick_grow_cleared (newlen);
824 if ((*m_vector)[id] == NULL)
825 (*m_vector)[id] = this->allocate_new ();
827 return (*m_vector)[id];
830 /* Getter for summary callgraph edge pointer. */
831 T* get (cgraph_edge *edge) ATTRIBUTE_PURE
833 return exists (edge) ? (*m_vector)[edge->get_summary_id ()] : NULL;
836 /* Remove edge from summary. */
837 using call_summary_base<T>::remove;
838 void remove (cgraph_edge *edge)
840 if (exists (edge))
842 int id = edge->get_summary_id ();
843 this->release ((*m_vector)[id]);
844 (*m_vector)[id] = NULL;
848 /* Return true if a summary for the given EDGE already exists. */
849 bool exists (cgraph_edge *edge)
851 int id = edge->get_summary_id ();
852 return (id != -1
853 && (unsigned)id < m_vector->length ()
854 && (*m_vector)[id] != NULL);
857 /* Symbol removal hook that is registered to symbol table. */
858 static void symtab_removal (cgraph_edge *edge, void *data);
860 /* Symbol duplication hook that is registered to symbol table. */
861 static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
862 void *data);
864 private:
865 virtual bool is_ggc ();
867 /* Summary is stored in the vector. */
868 vec <T *, V> *m_vector;
870 template <typename U> friend void gt_ggc_mx (fast_call_summary <U *, va_gc> * const &);
871 template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &);
872 template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &,
873 gt_pointer_operator, void *);
876 template <typename T, typename V>
877 fast_call_summary<T *, V>::~fast_call_summary ()
879 this->unregister_hooks ();
881 /* Release all summaries. */
882 for (unsigned i = 0; i < m_vector->length (); i++)
883 if ((*m_vector)[i] != NULL)
884 this->release ((*m_vector)[i]);
885 vec_free (m_vector);
888 template <typename T, typename V>
889 void
890 fast_call_summary<T *, V>::symtab_removal (cgraph_edge *edge, void *data)
892 fast_call_summary *summary = (fast_call_summary <T *, V> *) (data);
893 summary->remove (edge);
896 template <typename T, typename V>
897 void
898 fast_call_summary<T *, V>::symtab_duplication (cgraph_edge *edge1,
899 cgraph_edge *edge2, void *data)
901 fast_call_summary *summary = (fast_call_summary <T *, V> *) (data);
902 T *edge1_summary = NULL;
904 if (summary->m_initialize_when_cloning)
905 edge1_summary = summary->get_create (edge1);
906 else
907 edge1_summary = summary->get (edge1);
909 if (edge1_summary)
911 T *duplicate = summary->get_create (edge2);
912 summary->duplicate (edge1, edge2, edge1_summary, duplicate);
916 template <typename T, typename V>
917 inline bool
918 fast_call_summary<T *, V>::is_ggc ()
920 return is_same<V, va_gc>::value;
923 template <typename T>
924 void
925 gt_ggc_mx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED)
929 template <typename T>
930 void
931 gt_pch_nx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED)
935 template <typename T>
936 void
937 gt_pch_nx (fast_call_summary<T *, va_heap>* const& summary ATTRIBUTE_UNUSED,
938 gt_pointer_operator op ATTRIBUTE_UNUSED,
939 void *cookie ATTRIBUTE_UNUSED)
943 template <typename T>
944 void
945 gt_ggc_mx (fast_call_summary<T *, va_gc>* const &summary)
947 ggc_test_and_set_mark (summary->m_vector);
948 gt_ggc_mx (&summary->m_vector);
951 template <typename T>
952 void
953 gt_pch_nx (fast_call_summary<T *, va_gc> *const &)
955 gcc_unreachable ();
958 template <typename T>
959 void
960 gt_pch_nx (fast_call_summary<T *, va_gc> *const &, gt_pointer_operator, void *)
962 gcc_unreachable ();
965 #endif /* GCC_SYMBOL_SUMMARY_H */