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
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 CXX_MEM_STAT_INFO
):
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
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. */
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;
81 /* Allocates new data that are stored within map. */
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
)
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
;
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
>
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
137 class 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. */
155 class GTY((user
)) function_summary
<T
*>: public function_summary_base
<T
>
158 /* Default construction takes SYMTAB as an argument. */
159 function_summary (symbol_table
*symtab
, bool ggc
= false CXX_MEM_STAT_INFO
);
162 virtual ~function_summary ();
164 /* Traverses all summarys with a function F called with
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
)
177 T
**v
= &m_map
.get_or_insert (node
->get_uid (), &existed
);
179 *v
= this->allocate_new ();
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
);
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
,
221 /* Indication if we use ggc summary. */
225 /* Indication if we use ggc summary. */
226 virtual bool is_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
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
,
251 this->m_symtab_removal_hook
252 = this->m_symtab
->add_cgraph_removal_hook (function_summary::symtab_removal
,
254 this->m_symtab_duplication_hook
255 = this->m_symtab
->add_cgraph_duplication_hook (function_summary::symtab_duplication
,
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
>
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
>
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
>
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
);
301 summary
->duplicate (node
, node2
, v
, summary
->get_create (node2
));
305 template <typename T
>
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
>
315 gt_pch_nx (function_summary
<T
*> *const &)
320 template <typename T
>
322 gt_pch_nx (function_summary
<T
*> *const &, gt_pointer_operator
, void *)
327 /* Help template from std c++11. */
329 template<typename T
, typename U
>
332 static const bool value
= false;
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
344 template <class T
, class V
>
345 class fast_function_summary
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
>
359 /* Default construction takes SYMTAB as an argument. */
360 fast_function_summary (symbol_table
*symtab CXX_MEM_STAT_INFO
);
363 virtual ~fast_function_summary ();
365 /* Traverses all summarys with a function F called with
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 ();
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
)
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 ();
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
,
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
,
449 this->m_symtab_removal_hook
450 = this->m_symtab
->add_cgraph_removal_hook (fast_function_summary::symtab_removal
,
452 this->m_symtab_duplication_hook
453 = this->m_symtab
->add_cgraph_duplication_hook (fast_function_summary::symtab_duplication
,
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
]);
469 template <typename T
, typename V
>
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
>
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
>
493 fast_function_summary
<T
*, V
>::symtab_duplication (cgraph_node
*node
,
497 fast_function_summary
*summary
= (fast_function_summary
<T
*, V
> *) (data
);
498 if (summary
->m_duplication_enabled
)
500 T
*v
= summary
->get (node
);
504 T
*duplicate
= summary
->get_create (node2
);
505 summary
->duplicate (node
, node2
, v
, duplicate
);
510 template <typename T
, typename V
>
512 fast_function_summary
<T
*, V
>::is_ggc ()
514 return is_same
<V
, va_gc
>::value
;
517 template <typename T
>
519 gt_ggc_mx (fast_function_summary
<T
*, va_heap
>* const &)
523 template <typename T
>
525 gt_pch_nx (fast_function_summary
<T
*, va_heap
>* const &)
529 template <typename T
>
531 gt_pch_nx (fast_function_summary
<T
*, va_heap
>* const&, gt_pointer_operator
,
536 template <typename T
>
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
>
546 gt_pch_nx (fast_function_summary
<T
*, va_gc
> *const &)
551 template <typename T
>
553 gt_pch_nx (fast_function_summary
<T
*, va_gc
> *const &, gt_pointer_operator
,
559 /* Base class for call_summary and fast_call_summary classes. */
562 class call_summary_base
565 /* Default construction takes SYMTAB as an argument. */
566 call_summary_base (symbol_table
*symtab CXX_MEM_STAT_INFO
):
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
*)
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;
595 /* Allocates new data that are stored within map. */
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
)
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
;
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
>
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. */
654 /* Class to store auxiliary information about call graph edges. */
657 class GTY((user
)) call_summary
<T
*>: public call_summary_base
<T
>
660 /* Default construction takes SYMTAB as an argument. */
661 call_summary (symbol_table
*symtab
, bool ggc
= false
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
,
669 this->m_symtab_duplication_hook
670 = this->m_symtab
->add_edge_duplication_hook (call_summary::symtab_duplication
,
675 virtual ~call_summary ();
677 /* Traverses all summarys with an edge E called with
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
)
690 T
**v
= &m_map
.get_or_insert (edge
->get_uid (), &existed
);
692 *v
= this->allocate_new ();
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
);
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
,
731 /* Indication if we use ggc summary. */
735 /* Indication if we use ggc summary. */
736 virtual bool is_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
>
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
>
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
);
784 edge1_summary
= summary
->get (edge1
);
787 summary
->duplicate (edge1
, edge2
, edge1_summary
,
788 summary
->get_create (edge2
));
792 template <typename T
>
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
>
802 gt_pch_nx (call_summary
<T
*> *const &)
807 template <typename T
>
809 gt_pch_nx (call_summary
<T
*> *const &, gt_pointer_operator
, void *)
814 /* We want to pass just pointer types as argument for fast_call_summary
817 template <class T
, class V
>
818 class fast_call_summary
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
>
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
,
839 this->m_symtab_duplication_hook
840 = this->m_symtab
->add_edge_duplication_hook (fast_call_summary::symtab_duplication
,
845 virtual ~fast_call_summary ();
847 /* Traverses all summarys with an edge F called with
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 ();
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
)
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 ();
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
,
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
]);
932 template <typename T
, typename V
>
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
>
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
);
953 edge1_summary
= summary
->get (edge1
);
957 T
*duplicate
= summary
->get_create (edge2
);
958 summary
->duplicate (edge1
, edge2
, edge1_summary
, duplicate
);
963 template <typename T
, typename V
>
965 fast_call_summary
<T
*, V
>::is_ggc ()
967 return is_same
<V
, va_gc
>::value
;
970 template <typename T
>
972 gt_ggc_mx (fast_call_summary
<T
*, va_heap
>* const &summary ATTRIBUTE_UNUSED
)
976 template <typename T
>
978 gt_pch_nx (fast_call_summary
<T
*, va_heap
>* const &summary ATTRIBUTE_UNUSED
)
982 template <typename T
>
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
>
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
>
1000 gt_pch_nx (fast_call_summary
<T
*, va_gc
> *const &)
1005 template <typename T
>
1007 gt_pch_nx (fast_call_summary
<T
*, va_gc
> *const &, gt_pointer_operator
, void *)
1012 #endif /* GCC_SYMBOL_SUMMARY_H */