1 /* Callgraph summary data structure.
2 Copyright (C) 2014-2023 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
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
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. */
27 class function_summary_base
30 /* Default construction takes SYMTAB as an argument. */
31 function_summary_base (symbol_table
*symtab
,
32 cgraph_node_hook symtab_insertion
,
33 cgraph_node_hook symtab_removal
,
34 cgraph_2node_hook symtab_duplication
36 m_symtab (symtab
), m_symtab_insertion (symtab_insertion
),
37 m_symtab_removal (symtab_removal
),
38 m_symtab_duplication (symtab_duplication
),
39 m_symtab_insertion_hook (NULL
), m_symtab_duplication_hook (NULL
),
40 m_allocator ("function summary" PASS_MEM_STAT
)
42 enable_insertion_hook ();
44 = m_symtab
->add_cgraph_removal_hook (m_symtab_removal
, this);
45 enable_duplication_hook ();
48 /* Basic implementation of insert operation. */
49 virtual void insert (cgraph_node
*, T
*)
51 /* In most cases, it makes no sense to create summaries without
56 /* Basic implementation of removal operation. */
57 virtual void remove (cgraph_node
*, T
*) {}
59 /* Basic implementation of duplication operation. */
60 virtual void duplicate (cgraph_node
*, cgraph_node
*, T
*, T
*)
62 /* It makes no sense to not copy anything during duplication. */
66 /* Enable insertion hook invocation. */
67 void enable_insertion_hook ()
69 if (m_symtab_insertion_hook
== NULL
)
70 m_symtab_insertion_hook
71 = m_symtab
->add_cgraph_insertion_hook (m_symtab_insertion
, this);
74 /* Disable insertion hook invocation. */
75 void disable_insertion_hook ()
77 if (m_symtab_insertion_hook
!= NULL
)
79 m_symtab
->remove_cgraph_insertion_hook (m_symtab_insertion_hook
);
80 m_symtab_insertion_hook
= NULL
;
84 /* Enable duplication hook invocation. */
85 void enable_duplication_hook ()
87 if (m_symtab_duplication_hook
== NULL
)
88 m_symtab_duplication_hook
89 = m_symtab
->add_cgraph_duplication_hook (m_symtab_duplication
, this);
92 /* Enable duplication hook invocation. */
93 void disable_duplication_hook ()
95 if (m_symtab_duplication_hook
!= NULL
)
97 m_symtab
->remove_cgraph_duplication_hook (m_symtab_duplication_hook
);
98 m_symtab_duplication_hook
= NULL
;
103 /* Allocates new data that are stored within map. */
106 /* Call gcc_internal_because we do not want to call finalizer for
107 a type T. We call dtor explicitly. */
108 return is_ggc () ? new (ggc_internal_alloc (sizeof (T
))) T ()
109 : m_allocator
.allocate () ;
112 /* Release an item that is stored within map. */
113 void release (T
*item
)
118 m_allocator
.remove (item
);
121 /* Unregister all call-graph hooks. */
122 void unregister_hooks ();
124 /* Symbol table the summary is registered to. */
125 symbol_table
*m_symtab
;
127 /* Insertion function defined by a summary. */
128 cgraph_node_hook m_symtab_insertion
;
129 /* Removal function defined by a summary. */
130 cgraph_node_hook m_symtab_removal
;
131 /* Duplication function defined by a summary. */
132 cgraph_2node_hook m_symtab_duplication
;
134 /* Internal summary insertion hook pointer. */
135 cgraph_node_hook_list
*m_symtab_insertion_hook
;
136 /* Internal summary removal hook pointer. */
137 cgraph_node_hook_list
*m_symtab_removal_hook
;
138 /* Internal summary duplication hook pointer. */
139 cgraph_2node_hook_list
*m_symtab_duplication_hook
;
142 /* Return true when the summary uses GGC memory for allocation. */
143 virtual bool is_ggc () = 0;
145 /* Object allocator for heap allocation. */
146 object_allocator
<T
> m_allocator
;
149 template <typename T
>
151 function_summary_base
<T
>::unregister_hooks ()
153 disable_insertion_hook ();
154 m_symtab
->remove_cgraph_removal_hook (m_symtab_removal_hook
);
155 disable_duplication_hook ();
158 /* We want to pass just pointer types as argument for function_summary
162 class function_summary
168 /* Function summary is a helper class that is used to associate a data structure
169 related to a callgraph node. Typical usage can be seen in IPA passes which
170 create a temporary pass-related structures. The summary class registers
171 hooks that are triggered when a new node is inserted, duplicated and deleted.
172 A user of a summary class can ovewrite virtual methods than are triggered by
173 the summary if such hook is triggered. Apart from a callgraph node, the user
174 is given a data structure tied to the node.
176 The function summary class can work both with a heap-allocated memory and
177 a memory gained by garbage collected memory. */
180 class GTY((user
)) function_summary
<T
*>: public function_summary_base
<T
>
183 /* Default construction takes SYMTAB as an argument. */
184 function_summary (symbol_table
*symtab
, bool ggc
= false CXX_MEM_STAT_INFO
);
187 virtual ~function_summary ();
189 /* Traverses all summarys with a function F called with
191 template<typename Arg
, bool (*f
)(const T
&, Arg
)>
192 void traverse (Arg a
) const
194 m_map
.template traverse
<f
> (a
);
197 /* Getter for summary callgraph node pointer. If a summary for a node
198 does not exist it will be created. */
199 T
* get_create (cgraph_node
*node
)
202 T
**v
= &m_map
.get_or_insert (node
->get_uid (), &existed
);
204 *v
= this->allocate_new ();
209 /* Getter for summary callgraph node pointer. */
210 T
* get (cgraph_node
*node
) ATTRIBUTE_PURE
212 T
**v
= m_map
.get (node
->get_uid ());
213 return v
== NULL
? NULL
: *v
;
216 /* Remove node from summary. */
217 using function_summary_base
<T
>::remove
;
218 void remove (cgraph_node
*node
)
220 int uid
= node
->get_uid ();
221 T
**v
= m_map
.get (uid
);
229 /* Return true if a summary for the given NODE already exists. */
230 bool exists (cgraph_node
*node
)
232 return m_map
.get (node
->get_uid ()) != NULL
;
235 /* Symbol insertion hook that is registered to symbol table. */
236 static void symtab_insertion (cgraph_node
*node
, void *data
);
238 /* Symbol removal hook that is registered to symbol table. */
239 static void symtab_removal (cgraph_node
*node
, void *data
);
241 /* Symbol duplication hook that is registered to symbol table. */
242 static void symtab_duplication (cgraph_node
*node
, cgraph_node
*node2
,
246 /* Indication if we use ggc summary. */
250 /* Indication if we use ggc summary. */
251 bool is_ggc () final override
256 typedef int_hash
<int, 0, -1> map_hash
;
258 /* Main summary store, where summary ID is used as key. */
259 hash_map
<map_hash
, T
*> m_map
;
261 template <typename U
> friend void gt_ggc_mx (function_summary
<U
*> * const &);
262 template <typename U
> friend void gt_pch_nx (function_summary
<U
*> * const &);
263 template <typename U
> friend void gt_pch_nx (function_summary
<U
*> * const &,
264 gt_pointer_operator
, void *);
267 template <typename T
>
268 function_summary
<T
*>::function_summary (symbol_table
*symtab
, bool ggc
270 function_summary_base
<T
> (symtab
, function_summary::symtab_insertion
,
271 function_summary::symtab_removal
,
272 function_summary::symtab_duplication
274 m_ggc (ggc
), m_map (13, ggc
, true, GATHER_STATISTICS PASS_MEM_STAT
) {}
276 template <typename T
>
277 function_summary
<T
*>::~function_summary ()
279 this->unregister_hooks ();
281 /* Release all summaries. */
282 typedef typename hash_map
<map_hash
, T
*>::iterator map_iterator
;
283 for (map_iterator it
= m_map
.begin (); it
!= m_map
.end (); ++it
)
284 this->release ((*it
).second
);
287 template <typename T
>
289 function_summary
<T
*>::symtab_insertion (cgraph_node
*node
, void *data
)
291 gcc_checking_assert (node
->get_uid ());
292 function_summary
*summary
= (function_summary
<T
*> *) (data
);
293 summary
->insert (node
, summary
->get_create (node
));
296 template <typename T
>
298 function_summary
<T
*>::symtab_removal (cgraph_node
*node
, void *data
)
300 gcc_checking_assert (node
->get_uid ());
301 function_summary
*summary
= (function_summary
<T
*> *) (data
);
302 summary
->remove (node
);
305 template <typename T
>
307 function_summary
<T
*>::symtab_duplication (cgraph_node
*node
,
308 cgraph_node
*node2
, void *data
)
310 function_summary
*summary
= (function_summary
<T
*> *) (data
);
311 T
*v
= summary
->get (node
);
314 summary
->duplicate (node
, node2
, v
, summary
->get_create (node2
));
317 template <typename T
>
319 gt_ggc_mx(function_summary
<T
*>* const &summary
)
321 gcc_checking_assert (summary
->m_ggc
);
322 gt_ggc_mx (&summary
->m_map
);
325 template <typename T
>
327 gt_pch_nx (function_summary
<T
*> *const &)
332 template <typename T
>
334 gt_pch_nx (function_summary
<T
*> *const &, gt_pointer_operator
, void *)
339 /* Help template from std c++11. */
341 template<typename T
, typename U
>
344 static const bool value
= false;
348 struct is_same
<T
,T
> //specialization
350 static const bool value
= true;
353 /* We want to pass just pointer types as argument for fast_function_summary
356 template <class T
, class V
>
357 class fast_function_summary
360 fast_function_summary ();
363 /* Function vector summary is a fast implementation of function_summary that
364 utilizes vector as primary storage of summaries. */
366 template <class T
, class V
>
367 class GTY((user
)) fast_function_summary
<T
*, V
>
368 : public function_summary_base
<T
>
371 /* Default construction takes SYMTAB as an argument. */
372 fast_function_summary (symbol_table
*symtab CXX_MEM_STAT_INFO
);
375 virtual ~fast_function_summary ();
377 /* Traverses all summarys with a function F called with
379 template<typename Arg
, bool (*f
)(const T
&, Arg
)>
380 void traverse (Arg a
) const
382 for (unsigned i
= 0; i
< m_vector
->length (); i
++)
383 if ((*m_vector
[i
]) != NULL
)
384 f ((*m_vector
)[i
], a
);
387 /* Getter for summary callgraph node pointer. If a summary for a node
388 does not exist it will be created. */
389 T
* get_create (cgraph_node
*node
)
391 int id
= node
->get_summary_id ();
393 id
= this->m_symtab
->assign_summary_id (node
);
395 if ((unsigned int)id
>= m_vector
->length ())
396 vec_safe_grow_cleared (m_vector
,
397 this->m_symtab
->cgraph_max_summary_id
);
399 if ((*m_vector
)[id
] == NULL
)
400 (*m_vector
)[id
] = this->allocate_new ();
402 return (*m_vector
)[id
];
405 /* Getter for summary callgraph node pointer. */
406 T
* get (cgraph_node
*node
) ATTRIBUTE_PURE
408 return exists (node
) ? (*m_vector
)[node
->get_summary_id ()] : NULL
;
411 using function_summary_base
<T
>::remove
;
412 void remove (cgraph_node
*node
)
416 int id
= node
->get_summary_id ();
417 this->release ((*m_vector
)[id
]);
418 (*m_vector
)[id
] = NULL
;
422 /* Return true if a summary for the given NODE already exists. */
423 bool exists (cgraph_node
*node
)
425 int id
= node
->get_summary_id ();
427 && (unsigned int)id
< m_vector
->length ()
428 && (*m_vector
)[id
] != NULL
);
431 /* Symbol insertion hook that is registered to symbol table. */
432 static void symtab_insertion (cgraph_node
*node
, void *data
);
434 /* Symbol removal hook that is registered to symbol table. */
435 static void symtab_removal (cgraph_node
*node
, void *data
);
437 /* Symbol duplication hook that is registered to symbol table. */
438 static void symtab_duplication (cgraph_node
*node
, cgraph_node
*node2
,
442 bool is_ggc () final override
;
444 /* Summary is stored in the vector. */
445 vec
<T
*, V
> *m_vector
;
447 template <typename U
> friend void gt_ggc_mx (fast_function_summary
<U
*, va_gc
> * const &);
448 template <typename U
> friend void gt_pch_nx (fast_function_summary
<U
*, va_gc
> * const &);
449 template <typename U
> friend void gt_pch_nx (fast_function_summary
<U
*, va_gc
> * const &,
450 gt_pointer_operator
, void *);
453 template <typename T
, typename V
>
454 fast_function_summary
<T
*, V
>::fast_function_summary (symbol_table
*symtab
456 function_summary_base
<T
> (symtab
,
457 fast_function_summary::symtab_insertion
,
458 fast_function_summary::symtab_removal
,
459 fast_function_summary::symtab_duplication
460 PASS_MEM_STAT
), m_vector (NULL
)
462 vec_alloc (m_vector
, 13 PASS_MEM_STAT
);
465 template <typename T
, typename V
>
466 fast_function_summary
<T
*, V
>::~fast_function_summary ()
468 this->unregister_hooks ();
470 /* Release all summaries. */
471 for (unsigned i
= 0; i
< m_vector
->length (); i
++)
472 if ((*m_vector
)[i
] != NULL
)
473 this->release ((*m_vector
)[i
]);
477 template <typename T
, typename V
>
479 fast_function_summary
<T
*, V
>::symtab_insertion (cgraph_node
*node
, void *data
)
481 gcc_checking_assert (node
->get_uid ());
482 fast_function_summary
*summary
= (fast_function_summary
<T
*, V
> *) (data
);
483 summary
->insert (node
, summary
->get_create (node
));
486 template <typename T
, typename V
>
488 fast_function_summary
<T
*, V
>::symtab_removal (cgraph_node
*node
, void *data
)
490 gcc_checking_assert (node
->get_uid ());
491 fast_function_summary
*summary
= (fast_function_summary
<T
*, V
> *) (data
);
493 if (summary
->exists (node
))
494 summary
->remove (node
);
497 template <typename T
, typename V
>
499 fast_function_summary
<T
*, V
>::symtab_duplication (cgraph_node
*node
,
503 fast_function_summary
*summary
= (fast_function_summary
<T
*, V
> *) (data
);
504 T
*v
= summary
->get (node
);
508 T
*duplicate
= summary
->get_create (node2
);
509 summary
->duplicate (node
, node2
, v
, duplicate
);
513 template <typename T
, typename V
>
515 fast_function_summary
<T
*, V
>::is_ggc ()
517 return is_same
<V
, va_gc
>::value
;
520 template <typename T
>
522 gt_ggc_mx (fast_function_summary
<T
*, va_heap
>* const &)
526 template <typename T
>
528 gt_pch_nx (fast_function_summary
<T
*, va_heap
>* const &)
532 template <typename T
>
534 gt_pch_nx (fast_function_summary
<T
*, va_heap
>* const&, gt_pointer_operator
,
539 template <typename T
>
541 gt_ggc_mx (fast_function_summary
<T
*, va_gc
>* const &summary
)
543 ggc_test_and_set_mark (summary
->m_vector
);
544 gt_ggc_mx (summary
->m_vector
);
547 template <typename T
>
549 gt_pch_nx (fast_function_summary
<T
*, va_gc
> *const &)
554 template <typename T
>
556 gt_pch_nx (fast_function_summary
<T
*, va_gc
> *const &, gt_pointer_operator
,
562 /* Base class for call_summary and fast_call_summary classes. */
565 class call_summary_base
568 /* Default construction takes SYMTAB as an argument. */
569 call_summary_base (symbol_table
*symtab
, cgraph_edge_hook symtab_removal
,
570 cgraph_2edge_hook symtab_duplication CXX_MEM_STAT_INFO
):
571 m_symtab (symtab
), m_symtab_removal (symtab_removal
),
572 m_symtab_duplication (symtab_duplication
), m_symtab_duplication_hook (NULL
),
573 m_initialize_when_cloning (false),
574 m_allocator ("call summary" PASS_MEM_STAT
)
576 m_symtab_removal_hook
577 = m_symtab
->add_edge_removal_hook (m_symtab_removal
, this);
578 enable_duplication_hook ();
581 /* Basic implementation of removal operation. */
582 virtual void remove (cgraph_edge
*, T
*) {}
584 /* Basic implementation of duplication operation. */
585 virtual void duplicate (cgraph_edge
*, cgraph_edge
*, T
*, T
*)
590 /* Enable duplication hook invocation. */
591 void enable_duplication_hook ()
593 if (m_symtab_duplication_hook
== NULL
)
594 m_symtab_duplication_hook
595 = m_symtab
->add_edge_duplication_hook (m_symtab_duplication
,
599 /* Enable duplication hook invocation. */
600 void disable_duplication_hook ()
602 if (m_symtab_duplication_hook
!= NULL
)
604 m_symtab
->remove_edge_duplication_hook (m_symtab_duplication_hook
);
605 m_symtab_duplication_hook
= NULL
;
610 /* Allocates new data that are stored within map. */
613 /* Call gcc_internal_because we do not want to call finalizer for
614 a type T. We call dtor explicitly. */
615 return is_ggc () ? new (ggc_internal_alloc (sizeof (T
))) T ()
616 : m_allocator
.allocate ();
619 /* Release an item that is stored within map. */
620 void release (T
*item
)
625 m_allocator
.remove (item
);
628 /* Unregister all call-graph hooks. */
629 void unregister_hooks ();
631 /* Symbol table the summary is registered to. */
632 symbol_table
*m_symtab
;
634 /* Removal function defined by a summary. */
635 cgraph_edge_hook m_symtab_removal
;
636 /* Duplication function defined by a summary. */
637 cgraph_2edge_hook m_symtab_duplication
;
639 /* Internal summary removal hook pointer. */
640 cgraph_edge_hook_list
*m_symtab_removal_hook
;
641 /* Internal summary duplication hook pointer. */
642 cgraph_2edge_hook_list
*m_symtab_duplication_hook
;
643 /* Initialize summary for an edge that is cloned. */
644 bool m_initialize_when_cloning
;
647 /* Return true when the summary uses GGC memory for allocation. */
648 virtual bool is_ggc () = 0;
650 /* Object allocator for heap allocation. */
651 object_allocator
<T
> m_allocator
;
654 template <typename T
>
656 call_summary_base
<T
>::unregister_hooks ()
658 m_symtab
->remove_edge_removal_hook (m_symtab_removal_hook
);
659 disable_duplication_hook ();
662 /* An impossible class templated by non-pointers so, which makes sure that only
663 summaries gathering pointers can be created. */
672 /* Class to store auxiliary information about call graph edges. */
675 class GTY((user
)) call_summary
<T
*>: public call_summary_base
<T
>
678 /* Default construction takes SYMTAB as an argument. */
679 call_summary (symbol_table
*symtab
, bool ggc
= false
681 : call_summary_base
<T
> (symtab
, call_summary::symtab_removal
,
682 call_summary::symtab_duplication PASS_MEM_STAT
),
683 m_ggc (ggc
), m_map (13, ggc
, true, GATHER_STATISTICS PASS_MEM_STAT
) {}
686 virtual ~call_summary ();
688 /* Traverses all summarys with an edge E called with
690 template<typename Arg
, bool (*f
)(const T
&, Arg
)>
691 void traverse (Arg a
) const
693 m_map
.template traverse
<f
> (a
);
696 /* Getter for summary callgraph edge pointer.
697 If a summary for an edge does not exist, it will be created. */
698 T
* get_create (cgraph_edge
*edge
)
701 T
**v
= &m_map
.get_or_insert (edge
->get_uid (), &existed
);
703 *v
= this->allocate_new ();
708 /* Getter for summary callgraph edge pointer. */
709 T
* get (cgraph_edge
*edge
) ATTRIBUTE_PURE
711 T
**v
= m_map
.get (edge
->get_uid ());
712 return v
== NULL
? NULL
: *v
;
715 /* Remove edge from summary. */
716 using call_summary_base
<T
>::remove
;
717 void remove (cgraph_edge
*edge
)
719 int uid
= edge
->get_uid ();
720 T
**v
= m_map
.get (uid
);
728 /* Return true if a summary for the given EDGE already exists. */
729 bool exists (cgraph_edge
*edge
)
731 return m_map
.get (edge
->get_uid ()) != NULL
;
734 /* Symbol removal hook that is registered to symbol table. */
735 static void symtab_removal (cgraph_edge
*edge
, void *data
);
737 /* Symbol duplication hook that is registered to symbol table. */
738 static void symtab_duplication (cgraph_edge
*edge1
, cgraph_edge
*edge2
,
742 /* Indication if we use ggc summary. */
746 /* Indication if we use ggc summary. */
747 bool is_ggc () final override
752 typedef int_hash
<int, 0, -1> map_hash
;
754 /* Main summary store, where summary ID is used as key. */
755 hash_map
<map_hash
, T
*> m_map
;
757 template <typename U
> friend void gt_ggc_mx (call_summary
<U
*> * const &);
758 template <typename U
> friend void gt_pch_nx (call_summary
<U
*> * const &);
759 template <typename U
> friend void gt_pch_nx (call_summary
<U
*> * const &,
760 gt_pointer_operator
, void *);
763 template <typename T
>
764 call_summary
<T
*>::~call_summary ()
766 this->unregister_hooks ();
768 /* Release all summaries. */
769 typedef typename hash_map
<map_hash
, T
*>::iterator map_iterator
;
770 for (map_iterator it
= m_map
.begin (); it
!= m_map
.end (); ++it
)
771 this->release ((*it
).second
);
774 template <typename T
>
776 call_summary
<T
*>::symtab_removal (cgraph_edge
*edge
, void *data
)
778 call_summary
*summary
= (call_summary
<T
*> *) (data
);
779 summary
->remove (edge
);
782 template <typename T
>
784 call_summary
<T
*>::symtab_duplication (cgraph_edge
*edge1
,
785 cgraph_edge
*edge2
, void *data
)
787 call_summary
*summary
= (call_summary
<T
*> *) (data
);
788 T
*edge1_summary
= NULL
;
790 if (summary
->m_initialize_when_cloning
)
791 edge1_summary
= summary
->get_create (edge1
);
793 edge1_summary
= summary
->get (edge1
);
796 summary
->duplicate (edge1
, edge2
, edge1_summary
,
797 summary
->get_create (edge2
));
800 template <typename T
>
802 gt_ggc_mx(call_summary
<T
*>* const &summary
)
804 gcc_checking_assert (summary
->m_ggc
);
805 gt_ggc_mx (&summary
->m_map
);
808 template <typename T
>
810 gt_pch_nx (call_summary
<T
*> *const &)
815 template <typename T
>
817 gt_pch_nx (call_summary
<T
*> *const &, gt_pointer_operator
, void *)
822 /* We want to pass just pointer types as argument for fast_call_summary
825 template <class T
, class V
>
826 class fast_call_summary
829 fast_call_summary ();
832 /* Call vector summary is a fast implementation of call_summary that
833 utilizes vector as primary storage of summaries. */
835 template <class T
, class V
>
836 class GTY((user
)) fast_call_summary
<T
*, V
>: public call_summary_base
<T
>
839 /* Default construction takes SYMTAB as an argument. */
840 fast_call_summary (symbol_table
*symtab CXX_MEM_STAT_INFO
)
841 : call_summary_base
<T
> (symtab
, fast_call_summary::symtab_removal
,
842 fast_call_summary::symtab_duplication PASS_MEM_STAT
),
845 vec_alloc (m_vector
, 13 PASS_MEM_STAT
);
849 virtual ~fast_call_summary ();
851 /* Traverses all summarys with an edge F called with
853 template<typename Arg
, bool (*f
)(const T
&, Arg
)>
854 void traverse (Arg a
) const
856 for (unsigned i
= 0; i
< m_vector
->length (); i
++)
857 if ((*m_vector
[i
]) != NULL
)
858 f ((*m_vector
)[i
], a
);
861 /* Getter for summary callgraph edge pointer.
862 If a summary for an edge does not exist, it will be created. */
863 T
* get_create (cgraph_edge
*edge
)
865 int id
= edge
->get_summary_id ();
867 id
= this->m_symtab
->assign_summary_id (edge
);
869 if ((unsigned)id
>= m_vector
->length ())
870 vec_safe_grow_cleared (m_vector
, this->m_symtab
->edges_max_summary_id
);
872 if ((*m_vector
)[id
] == NULL
)
873 (*m_vector
)[id
] = this->allocate_new ();
875 return (*m_vector
)[id
];
878 /* Getter for summary callgraph edge pointer. */
879 T
* get (cgraph_edge
*edge
) ATTRIBUTE_PURE
881 return exists (edge
) ? (*m_vector
)[edge
->get_summary_id ()] : NULL
;
884 /* Remove edge from summary. */
885 using call_summary_base
<T
>::remove
;
886 void remove (cgraph_edge
*edge
)
890 int id
= edge
->get_summary_id ();
891 this->release ((*m_vector
)[id
]);
892 (*m_vector
)[id
] = NULL
;
896 /* Return true if a summary for the given EDGE already exists. */
897 bool exists (cgraph_edge
*edge
)
899 int id
= edge
->get_summary_id ();
901 && (unsigned)id
< m_vector
->length ()
902 && (*m_vector
)[id
] != NULL
);
905 /* Symbol removal hook that is registered to symbol table. */
906 static void symtab_removal (cgraph_edge
*edge
, void *data
);
908 /* Symbol duplication hook that is registered to symbol table. */
909 static void symtab_duplication (cgraph_edge
*edge1
, cgraph_edge
*edge2
,
913 bool is_ggc () final override
;
915 /* Summary is stored in the vector. */
916 vec
<T
*, V
> *m_vector
;
918 template <typename U
> friend void gt_ggc_mx (fast_call_summary
<U
*, va_gc
> * const &);
919 template <typename U
> friend void gt_pch_nx (fast_call_summary
<U
*, va_gc
> * const &);
920 template <typename U
> friend void gt_pch_nx (fast_call_summary
<U
*, va_gc
> * const &,
921 gt_pointer_operator
, void *);
924 template <typename T
, typename V
>
925 fast_call_summary
<T
*, V
>::~fast_call_summary ()
927 this->unregister_hooks ();
929 /* Release all summaries. */
930 for (unsigned i
= 0; i
< m_vector
->length (); i
++)
931 if ((*m_vector
)[i
] != NULL
)
932 this->release ((*m_vector
)[i
]);
936 template <typename T
, typename V
>
938 fast_call_summary
<T
*, V
>::symtab_removal (cgraph_edge
*edge
, void *data
)
940 fast_call_summary
*summary
= (fast_call_summary
<T
*, V
> *) (data
);
941 summary
->remove (edge
);
944 template <typename T
, typename V
>
946 fast_call_summary
<T
*, V
>::symtab_duplication (cgraph_edge
*edge1
,
947 cgraph_edge
*edge2
, void *data
)
949 fast_call_summary
*summary
= (fast_call_summary
<T
*, V
> *) (data
);
950 T
*edge1_summary
= NULL
;
952 if (summary
->m_initialize_when_cloning
)
953 edge1_summary
= summary
->get_create (edge1
);
955 edge1_summary
= summary
->get (edge1
);
959 T
*duplicate
= summary
->get_create (edge2
);
960 summary
->duplicate (edge1
, edge2
, edge1_summary
, duplicate
);
964 template <typename T
, typename V
>
966 fast_call_summary
<T
*, V
>::is_ggc ()
968 return is_same
<V
, va_gc
>::value
;
971 template <typename T
>
973 gt_ggc_mx (fast_call_summary
<T
*, va_heap
>* const &summary ATTRIBUTE_UNUSED
)
977 template <typename T
>
979 gt_pch_nx (fast_call_summary
<T
*, va_heap
>* const &summary ATTRIBUTE_UNUSED
)
983 template <typename T
>
985 gt_pch_nx (fast_call_summary
<T
*, va_heap
>* const& summary ATTRIBUTE_UNUSED
,
986 gt_pointer_operator op ATTRIBUTE_UNUSED
,
987 void *cookie ATTRIBUTE_UNUSED
)
991 template <typename T
>
993 gt_ggc_mx (fast_call_summary
<T
*, va_gc
>* const &summary
)
995 ggc_test_and_set_mark (summary
->m_vector
);
996 gt_ggc_mx (&summary
->m_vector
);
999 template <typename T
>
1001 gt_pch_nx (fast_call_summary
<T
*, va_gc
> *const &)
1006 template <typename T
>
1008 gt_pch_nx (fast_call_summary
<T
*, va_gc
> *const &, gt_pointer_operator
, void *)
1013 #endif /* GCC_SYMBOL_SUMMARY_H */