[RS6000] biarch test fail
[official-gcc.git] / gcc / symbol-summary.h
blobaf5f4e6da62cb7aba5a37836bbf3b0152416cc52
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_duplication_enabled (true),
35 m_allocator ("function summary" PASS_MEM_STAT)
38 /* Basic implementation of insert operation. */
39 virtual void insert (cgraph_node *, T *)
41 /* In most cases, it makes no sense to create summaries without
42 initializing them. */
43 gcc_unreachable ();
46 /* Basic implementation of removal operation. */
47 virtual void remove (cgraph_node *, T *) {}
49 /* Basic implementation of duplication operation. */
50 virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *)
52 /* It makes no sense to not copy anything during duplication. */
53 gcc_unreachable ();
56 /* Enable insertion hook invocation. */
57 void enable_insertion_hook ()
59 m_insertion_enabled = true;
62 /* Enable insertion hook invocation. */
63 void disable_insertion_hook ()
65 m_insertion_enabled = false;
68 /* Enable duplication hook invocation. */
69 void enable_duplication_hook ()
71 m_duplication_enabled = true;
74 /* Enable duplication hook invocation. */
75 void disable_duplication_hook ()
77 m_duplication_enabled = false;
80 protected:
81 /* Allocates new data that are stored within map. */
82 T* allocate_new ()
84 /* Call gcc_internal_because we do not want to call finalizer for
85 a type T. We call dtor explicitly. */
86 return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
87 : m_allocator.allocate () ;
90 /* Release an item that is stored within map. */
91 void release (T *item)
93 if (is_ggc ())
94 ggc_delete (item);
95 else
96 m_allocator.remove (item);
99 /* Unregister all call-graph hooks. */
100 void unregister_hooks ();
102 /* Internal summary insertion hook pointer. */
103 cgraph_node_hook_list *m_symtab_insertion_hook;
104 /* Internal summary removal hook pointer. */
105 cgraph_node_hook_list *m_symtab_removal_hook;
106 /* Internal summary duplication hook pointer. */
107 cgraph_2node_hook_list *m_symtab_duplication_hook;
108 /* Symbol table the summary is registered to. */
109 symbol_table *m_symtab;
111 /* Indicates if insertion hook is enabled. */
112 bool m_insertion_enabled;
113 /* Indicates if duplication hook is enabled. */
114 bool m_duplication_enabled;
116 private:
117 /* Return true when the summary uses GGC memory for allocation. */
118 virtual bool is_ggc () = 0;
120 /* Object allocator for heap allocation. */
121 object_allocator<T> m_allocator;
124 template <typename T>
125 void
126 function_summary_base<T>::unregister_hooks ()
128 m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
129 m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
130 m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
133 /* We want to pass just pointer types as argument for function_summary
134 template class. */
136 template <class T>
137 class function_summary
139 private:
140 function_summary();
143 /* Function summary is a helper class that is used to associate a data structure
144 related to a callgraph node. Typical usage can be seen in IPA passes which
145 create a temporary pass-related structures. The summary class registers
146 hooks that are triggered when a new node is inserted, duplicated and deleted.
147 A user of a summary class can ovewrite virtual methods than are triggered by
148 the summary if such hook is triggered. Apart from a callgraph node, the user
149 is given a data structure tied to the node.
151 The function summary class can work both with a heap-allocated memory and
152 a memory gained by garbage collected memory. */
154 template <class T>
155 class GTY((user)) function_summary <T *>: public function_summary_base<T>
157 public:
158 /* Default construction takes SYMTAB as an argument. */
159 function_summary (symbol_table *symtab, bool ggc = false CXX_MEM_STAT_INFO);
161 /* Destructor. */
162 virtual ~function_summary ();
164 /* Traverses all summarys with a function F called with
165 ARG as argument. */
166 template<typename Arg, bool (*f)(const T &, Arg)>
167 void traverse (Arg a) const
169 m_map.traverse <f> (a);
172 /* Getter for summary callgraph node pointer. If a summary for a node
173 does not exist it will be created. */
174 T* get_create (cgraph_node *node)
176 bool existed;
177 T **v = &m_map.get_or_insert (node->get_uid (), &existed);
178 if (!existed)
179 *v = this->allocate_new ();
181 return *v;
184 /* Getter for summary callgraph node pointer. */
185 T* get (cgraph_node *node) ATTRIBUTE_PURE
187 T **v = m_map.get (node->get_uid ());
188 return v == NULL ? NULL : *v;
191 /* Remove node from summary. */
192 using function_summary_base<T>::remove;
193 void remove (cgraph_node *node)
195 int uid = node->get_uid ();
196 T **v = m_map.get (uid);
197 if (v)
199 m_map.remove (uid);
200 this->release (*v);
204 /* Return true if a summary for the given NODE already exists. */
205 bool exists (cgraph_node *node)
207 return m_map.get (node->get_uid ()) != NULL;
210 /* Symbol insertion hook that is registered to symbol table. */
211 static void symtab_insertion (cgraph_node *node, void *data);
213 /* Symbol removal hook that is registered to symbol table. */
214 static void symtab_removal (cgraph_node *node, void *data);
216 /* Symbol duplication hook that is registered to symbol table. */
217 static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
218 void *data);
220 protected:
221 /* Indication if we use ggc summary. */
222 bool m_ggc;
224 private:
225 /* Indication if we use ggc summary. */
226 virtual bool is_ggc ()
228 return m_ggc;
231 typedef int_hash <int, 0, -1> map_hash;
233 /* Main summary store, where summary ID is used as key. */
234 hash_map <map_hash, T *> m_map;
236 template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &);
237 template <typename U> friend void gt_pch_nx (function_summary <U *> * const &);
238 template <typename U> friend void gt_pch_nx (function_summary <U *> * const &,
239 gt_pointer_operator, void *);
242 template <typename T>
243 function_summary<T *>::function_summary (symbol_table *symtab, bool ggc
244 MEM_STAT_DECL):
245 function_summary_base<T> (symtab PASS_MEM_STAT), m_ggc (ggc),
246 m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT)
248 this->m_symtab_insertion_hook
249 = this->m_symtab->add_cgraph_insertion_hook (function_summary::symtab_insertion,
250 this);
251 this->m_symtab_removal_hook
252 = this->m_symtab->add_cgraph_removal_hook (function_summary::symtab_removal,
253 this);
254 this->m_symtab_duplication_hook
255 = this->m_symtab->add_cgraph_duplication_hook (function_summary::symtab_duplication,
256 this);
259 template <typename T>
260 function_summary<T *>::~function_summary ()
262 this->unregister_hooks ();
264 /* Release all summaries. */
265 typedef typename hash_map <map_hash, T *>::iterator map_iterator;
266 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
267 this->release ((*it).second);
270 template <typename T>
271 void
272 function_summary<T *>::symtab_insertion (cgraph_node *node, void *data)
274 gcc_checking_assert (node->get_uid ());
275 function_summary *summary = (function_summary <T *> *) (data);
277 if (summary->m_insertion_enabled)
278 summary->insert (node, summary->get_create (node));
281 template <typename T>
282 void
283 function_summary<T *>::symtab_removal (cgraph_node *node, void *data)
285 gcc_checking_assert (node->get_uid ());
286 function_summary *summary = (function_summary <T *> *) (data);
287 summary->remove (node);
290 template <typename T>
291 void
292 function_summary<T *>::symtab_duplication (cgraph_node *node,
293 cgraph_node *node2, void *data)
295 function_summary *summary = (function_summary <T *> *) (data);
296 if (summary->m_duplication_enabled)
298 T *v = summary->get (node);
300 if (v)
301 summary->duplicate (node, node2, v, summary->get_create (node2));
305 template <typename T>
306 void
307 gt_ggc_mx(function_summary<T *>* const &summary)
309 gcc_checking_assert (summary->m_ggc);
310 gt_ggc_mx (&summary->m_map);
313 template <typename T>
314 void
315 gt_pch_nx (function_summary<T *> *const &)
317 gcc_unreachable ();
320 template <typename T>
321 void
322 gt_pch_nx (function_summary<T *> *const &, gt_pointer_operator, void *)
324 gcc_unreachable ();
327 /* Help template from std c++11. */
329 template<typename T, typename U>
330 struct is_same
332 static const bool value = false;
335 template<typename T>
336 struct is_same<T,T> //specialization
338 static const bool value = true;
341 /* We want to pass just pointer types as argument for fast_function_summary
342 template class. */
344 template <class T, class V>
345 class fast_function_summary
347 private:
348 fast_function_summary ();
351 /* Function vector summary is a fast implementation of function_summary that
352 utilizes vector as primary storage of summaries. */
354 template <class T, class V>
355 class GTY((user)) fast_function_summary <T *, V>
356 : public function_summary_base<T>
358 public:
359 /* Default construction takes SYMTAB as an argument. */
360 fast_function_summary (symbol_table *symtab CXX_MEM_STAT_INFO);
362 /* Destructor. */
363 virtual ~fast_function_summary ();
365 /* Traverses all summarys with a function F called with
366 ARG as argument. */
367 template<typename Arg, bool (*f)(const T &, Arg)>
368 void traverse (Arg a) const
370 for (unsigned i = 0; i < m_vector->length (); i++)
371 if ((*m_vector[i]) != NULL)
372 f ((*m_vector)[i], a);
375 /* Getter for summary callgraph node pointer. If a summary for a node
376 does not exist it will be created. */
377 T* get_create (cgraph_node *node)
379 int id = node->get_summary_id ();
380 if (id == -1)
381 id = this->m_symtab->assign_summary_id (node);
383 if ((unsigned int)id >= m_vector->length ())
384 vec_safe_grow_cleared (m_vector,
385 this->m_symtab->cgraph_max_summary_id);
387 if ((*m_vector)[id] == NULL)
388 (*m_vector)[id] = this->allocate_new ();
390 return (*m_vector)[id];
393 /* Getter for summary callgraph node pointer. */
394 T* get (cgraph_node *node) ATTRIBUTE_PURE
396 return exists (node) ? (*m_vector)[node->get_summary_id ()] : NULL;
399 using function_summary_base<T>::remove;
400 void remove (cgraph_node *node)
402 if (exists (node))
404 int id = node->get_summary_id ();
405 this->release ((*m_vector)[id]);
406 (*m_vector)[id] = NULL;
410 /* Return true if a summary for the given NODE already exists. */
411 bool exists (cgraph_node *node)
413 int id = node->get_summary_id ();
414 return (id != -1
415 && (unsigned int)id < m_vector->length ()
416 && (*m_vector)[id] != NULL);
419 /* Symbol insertion hook that is registered to symbol table. */
420 static void symtab_insertion (cgraph_node *node, void *data);
422 /* Symbol removal hook that is registered to symbol table. */
423 static void symtab_removal (cgraph_node *node, void *data);
425 /* Symbol duplication hook that is registered to symbol table. */
426 static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
427 void *data);
429 private:
430 virtual bool is_ggc ();
432 /* Summary is stored in the vector. */
433 vec <T *, V> *m_vector;
435 template <typename U> friend void gt_ggc_mx (fast_function_summary <U *, va_gc> * const &);
436 template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &);
437 template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &,
438 gt_pointer_operator, void *);
441 template <typename T, typename V>
442 fast_function_summary<T *, V>::fast_function_summary (symbol_table *symtab MEM_STAT_DECL):
443 function_summary_base<T> (symtab PASS_MEM_STAT), m_vector (NULL)
445 vec_alloc (m_vector, 13 PASS_MEM_STAT);
446 this->m_symtab_insertion_hook
447 = this->m_symtab->add_cgraph_insertion_hook (fast_function_summary::symtab_insertion,
448 this);
449 this->m_symtab_removal_hook
450 = this->m_symtab->add_cgraph_removal_hook (fast_function_summary::symtab_removal,
451 this);
452 this->m_symtab_duplication_hook
453 = this->m_symtab->add_cgraph_duplication_hook (fast_function_summary::symtab_duplication,
454 this);
457 template <typename T, typename V>
458 fast_function_summary<T *, V>::~fast_function_summary ()
460 this->unregister_hooks ();
462 /* Release all summaries. */
463 for (unsigned i = 0; i < m_vector->length (); i++)
464 if ((*m_vector)[i] != NULL)
465 this->release ((*m_vector)[i]);
466 vec_free (m_vector);
469 template <typename T, typename V>
470 void
471 fast_function_summary<T *, V>::symtab_insertion (cgraph_node *node, void *data)
473 gcc_checking_assert (node->get_uid ());
474 fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
476 if (summary->m_insertion_enabled)
477 summary->insert (node, summary->get_create (node));
480 template <typename T, typename V>
481 void
482 fast_function_summary<T *, V>::symtab_removal (cgraph_node *node, void *data)
484 gcc_checking_assert (node->get_uid ());
485 fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
487 if (summary->exists (node))
488 summary->remove (node);
491 template <typename T, typename V>
492 void
493 fast_function_summary<T *, V>::symtab_duplication (cgraph_node *node,
494 cgraph_node *node2,
495 void *data)
497 fast_function_summary *summary = (fast_function_summary <T *, V> *) (data);
498 if (summary->m_duplication_enabled)
500 T *v = summary->get (node);
502 if (v)
504 T *duplicate = summary->get_create (node2);
505 summary->duplicate (node, node2, v, duplicate);
510 template <typename T, typename V>
511 inline bool
512 fast_function_summary<T *, V>::is_ggc ()
514 return is_same<V, va_gc>::value;
517 template <typename T>
518 void
519 gt_ggc_mx (fast_function_summary<T *, va_heap>* const &)
523 template <typename T>
524 void
525 gt_pch_nx (fast_function_summary<T *, va_heap>* const &)
529 template <typename T>
530 void
531 gt_pch_nx (fast_function_summary<T *, va_heap>* const&, gt_pointer_operator,
532 void *)
536 template <typename T>
537 void
538 gt_ggc_mx (fast_function_summary<T *, va_gc>* const &summary)
540 ggc_test_and_set_mark (summary->m_vector);
541 gt_ggc_mx (summary->m_vector);
544 template <typename T>
545 void
546 gt_pch_nx (fast_function_summary<T *, va_gc> *const &)
548 gcc_unreachable ();
551 template <typename T>
552 void
553 gt_pch_nx (fast_function_summary<T *, va_gc> *const &, gt_pointer_operator,
554 void *)
556 gcc_unreachable ();
559 /* Base class for call_summary and fast_call_summary classes. */
561 template <class T>
562 class call_summary_base
564 public:
565 /* Default construction takes SYMTAB as an argument. */
566 call_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO):
567 m_symtab (symtab),
568 m_initialize_when_cloning (false),
569 m_duplication_enabled (true),
570 m_allocator ("call summary" PASS_MEM_STAT)
573 /* Basic implementation of removal operation. */
574 virtual void remove (cgraph_edge *, T *) {}
576 /* Basic implementation of duplication operation. */
577 virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *)
579 gcc_unreachable ();
582 /* Enable duplication hook invocation. */
583 void enable_duplication_hook ()
585 m_duplication_enabled = true;
588 /* Enable duplication hook invocation. */
589 void disable_duplication_hook ()
591 m_duplication_enabled = false;
594 protected:
595 /* Allocates new data that are stored within map. */
596 T* allocate_new ()
598 /* Call gcc_internal_because we do not want to call finalizer for
599 a type T. We call dtor explicitly. */
600 return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
601 : m_allocator.allocate ();
604 /* Release an item that is stored within map. */
605 void release (T *item)
607 if (is_ggc ())
608 ggc_delete (item);
609 else
610 m_allocator.remove (item);
613 /* Unregister all call-graph hooks. */
614 void unregister_hooks ();
616 /* Symbol table the summary is registered to. */
617 symbol_table *m_symtab;
619 /* Internal summary removal hook pointer. */
620 cgraph_edge_hook_list *m_symtab_removal_hook;
621 /* Internal summary duplication hook pointer. */
622 cgraph_2edge_hook_list *m_symtab_duplication_hook;
623 /* Initialize summary for an edge that is cloned. */
624 bool m_initialize_when_cloning;
625 /* Indicates if duplication hook is enabled. */
626 bool m_duplication_enabled;
628 private:
629 /* Return true when the summary uses GGC memory for allocation. */
630 virtual bool is_ggc () = 0;
632 /* Object allocator for heap allocation. */
633 object_allocator<T> m_allocator;
636 template <typename T>
637 void
638 call_summary_base<T>::unregister_hooks ()
640 m_symtab->remove_edge_removal_hook (m_symtab_removal_hook);
641 m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook);
644 /* An impossible class templated by non-pointers so, which makes sure that only
645 summaries gathering pointers can be created. */
647 template <class T>
648 class call_summary
650 private:
651 call_summary ();
654 /* Class to store auxiliary information about call graph edges. */
656 template <class T>
657 class GTY((user)) call_summary <T *>: public call_summary_base<T>
659 public:
660 /* Default construction takes SYMTAB as an argument. */
661 call_summary (symbol_table *symtab, bool ggc = false
662 CXX_MEM_STAT_INFO)
663 : call_summary_base<T> (symtab PASS_MEM_STAT), m_ggc (ggc),
664 m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT)
666 this->m_symtab_removal_hook
667 = this->m_symtab->add_edge_removal_hook (call_summary::symtab_removal,
668 this);
669 this->m_symtab_duplication_hook
670 = this->m_symtab->add_edge_duplication_hook (call_summary::symtab_duplication,
671 this);
674 /* Destructor. */
675 virtual ~call_summary ();
677 /* Traverses all summarys with an edge E called with
678 ARG as argument. */
679 template<typename Arg, bool (*f)(const T &, Arg)>
680 void traverse (Arg a) const
682 m_map.traverse <f> (a);
685 /* Getter for summary callgraph edge pointer.
686 If a summary for an edge does not exist, it will be created. */
687 T* get_create (cgraph_edge *edge)
689 bool existed;
690 T **v = &m_map.get_or_insert (edge->get_uid (), &existed);
691 if (!existed)
692 *v = this->allocate_new ();
694 return *v;
697 /* Getter for summary callgraph edge pointer. */
698 T* get (cgraph_edge *edge) ATTRIBUTE_PURE
700 T **v = m_map.get (edge->get_uid ());
701 return v == NULL ? NULL : *v;
704 /* Remove edge from summary. */
705 using call_summary_base<T>::remove;
706 void remove (cgraph_edge *edge)
708 int uid = edge->get_uid ();
709 T **v = m_map.get (uid);
710 if (v)
712 m_map.remove (uid);
713 this->release (*v);
717 /* Return true if a summary for the given EDGE already exists. */
718 bool exists (cgraph_edge *edge)
720 return m_map.get (edge->get_uid ()) != NULL;
723 /* Symbol removal hook that is registered to symbol table. */
724 static void symtab_removal (cgraph_edge *edge, void *data);
726 /* Symbol duplication hook that is registered to symbol table. */
727 static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
728 void *data);
730 protected:
731 /* Indication if we use ggc summary. */
732 bool m_ggc;
734 private:
735 /* Indication if we use ggc summary. */
736 virtual bool is_ggc ()
738 return m_ggc;
741 typedef int_hash <int, 0, -1> map_hash;
743 /* Main summary store, where summary ID is used as key. */
744 hash_map <map_hash, T *> m_map;
746 template <typename U> friend void gt_ggc_mx (call_summary <U *> * const &);
747 template <typename U> friend void gt_pch_nx (call_summary <U *> * const &);
748 template <typename U> friend void gt_pch_nx (call_summary <U *> * const &,
749 gt_pointer_operator, void *);
752 template <typename T>
753 call_summary<T *>::~call_summary ()
755 this->unregister_hooks ();
757 /* Release all summaries. */
758 typedef typename hash_map <map_hash, T *>::iterator map_iterator;
759 for (map_iterator it = m_map.begin (); it != m_map.end (); ++it)
760 this->release ((*it).second);
763 template <typename T>
764 void
765 call_summary<T *>::symtab_removal (cgraph_edge *edge, void *data)
767 call_summary *summary = (call_summary <T *> *) (data);
768 summary->remove (edge);
771 template <typename T>
772 void
773 call_summary<T *>::symtab_duplication (cgraph_edge *edge1,
774 cgraph_edge *edge2, void *data)
776 call_summary *summary = (call_summary <T *> *) (data);
777 if (summary->m_duplication_enabled)
779 T *edge1_summary = NULL;
781 if (summary->m_initialize_when_cloning)
782 edge1_summary = summary->get_create (edge1);
783 else
784 edge1_summary = summary->get (edge1);
786 if (edge1_summary)
787 summary->duplicate (edge1, edge2, edge1_summary,
788 summary->get_create (edge2));
792 template <typename T>
793 void
794 gt_ggc_mx(call_summary<T *>* const &summary)
796 gcc_checking_assert (summary->m_ggc);
797 gt_ggc_mx (&summary->m_map);
800 template <typename T>
801 void
802 gt_pch_nx (call_summary<T *> *const &)
804 gcc_unreachable ();
807 template <typename T>
808 void
809 gt_pch_nx (call_summary<T *> *const &, gt_pointer_operator, void *)
811 gcc_unreachable ();
814 /* We want to pass just pointer types as argument for fast_call_summary
815 template class. */
817 template <class T, class V>
818 class fast_call_summary
820 private:
821 fast_call_summary ();
824 /* Call vector summary is a fast implementation of call_summary that
825 utilizes vector as primary storage of summaries. */
827 template <class T, class V>
828 class GTY((user)) fast_call_summary <T *, V>: public call_summary_base<T>
830 public:
831 /* Default construction takes SYMTAB as an argument. */
832 fast_call_summary (symbol_table *symtab CXX_MEM_STAT_INFO)
833 : call_summary_base<T> (symtab PASS_MEM_STAT), m_vector (NULL)
835 vec_alloc (m_vector, 13 PASS_MEM_STAT);
836 this->m_symtab_removal_hook
837 = this->m_symtab->add_edge_removal_hook (fast_call_summary::symtab_removal,
838 this);
839 this->m_symtab_duplication_hook
840 = this->m_symtab->add_edge_duplication_hook (fast_call_summary::symtab_duplication,
841 this);
844 /* Destructor. */
845 virtual ~fast_call_summary ();
847 /* Traverses all summarys with an edge F called with
848 ARG as argument. */
849 template<typename Arg, bool (*f)(const T &, Arg)>
850 void traverse (Arg a) const
852 for (unsigned i = 0; i < m_vector->length (); i++)
853 if ((*m_vector[i]) != NULL)
854 f ((*m_vector)[i], a);
857 /* Getter for summary callgraph edge pointer.
858 If a summary for an edge does not exist, it will be created. */
859 T* get_create (cgraph_edge *edge)
861 int id = edge->get_summary_id ();
862 if (id == -1)
863 id = this->m_symtab->assign_summary_id (edge);
865 if ((unsigned)id >= m_vector->length ())
866 vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id);
868 if ((*m_vector)[id] == NULL)
869 (*m_vector)[id] = this->allocate_new ();
871 return (*m_vector)[id];
874 /* Getter for summary callgraph edge pointer. */
875 T* get (cgraph_edge *edge) ATTRIBUTE_PURE
877 return exists (edge) ? (*m_vector)[edge->get_summary_id ()] : NULL;
880 /* Remove edge from summary. */
881 using call_summary_base<T>::remove;
882 void remove (cgraph_edge *edge)
884 if (exists (edge))
886 int id = edge->get_summary_id ();
887 this->release ((*m_vector)[id]);
888 (*m_vector)[id] = NULL;
892 /* Return true if a summary for the given EDGE already exists. */
893 bool exists (cgraph_edge *edge)
895 int id = edge->get_summary_id ();
896 return (id != -1
897 && (unsigned)id < m_vector->length ()
898 && (*m_vector)[id] != NULL);
901 /* Symbol removal hook that is registered to symbol table. */
902 static void symtab_removal (cgraph_edge *edge, void *data);
904 /* Symbol duplication hook that is registered to symbol table. */
905 static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2,
906 void *data);
908 private:
909 virtual bool is_ggc ();
911 /* Summary is stored in the vector. */
912 vec <T *, V> *m_vector;
914 template <typename U> friend void gt_ggc_mx (fast_call_summary <U *, va_gc> * const &);
915 template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &);
916 template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &,
917 gt_pointer_operator, void *);
920 template <typename T, typename V>
921 fast_call_summary<T *, V>::~fast_call_summary ()
923 this->unregister_hooks ();
925 /* Release all summaries. */
926 for (unsigned i = 0; i < m_vector->length (); i++)
927 if ((*m_vector)[i] != NULL)
928 this->release ((*m_vector)[i]);
929 vec_free (m_vector);
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 if (summary->m_duplication_enabled)
948 T *edge1_summary = NULL;
950 if (summary->m_initialize_when_cloning)
951 edge1_summary = summary->get_create (edge1);
952 else
953 edge1_summary = summary->get (edge1);
955 if (edge1_summary)
957 T *duplicate = summary->get_create (edge2);
958 summary->duplicate (edge1, edge2, edge1_summary, duplicate);
963 template <typename T, typename V>
964 inline bool
965 fast_call_summary<T *, V>::is_ggc ()
967 return is_same<V, va_gc>::value;
970 template <typename T>
971 void
972 gt_ggc_mx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED)
976 template <typename T>
977 void
978 gt_pch_nx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED)
982 template <typename T>
983 void
984 gt_pch_nx (fast_call_summary<T *, va_heap>* const& summary ATTRIBUTE_UNUSED,
985 gt_pointer_operator op ATTRIBUTE_UNUSED,
986 void *cookie ATTRIBUTE_UNUSED)
990 template <typename T>
991 void
992 gt_ggc_mx (fast_call_summary<T *, va_gc>* const &summary)
994 ggc_test_and_set_mark (summary->m_vector);
995 gt_ggc_mx (&summary->m_vector);
998 template <typename T>
999 void
1000 gt_pch_nx (fast_call_summary<T *, va_gc> *const &)
1002 gcc_unreachable ();
1005 template <typename T>
1006 void
1007 gt_pch_nx (fast_call_summary<T *, va_gc> *const &, gt_pointer_operator, void *)
1009 gcc_unreachable ();
1012 #endif /* GCC_SYMBOL_SUMMARY_H */