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_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;
59 /* Allocates new data that are stored within map. */
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
)
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
;
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
>
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
113 class 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. */
131 class GTY((user
)) function_summary
<T
*>: public function_summary_base
<T
>
134 /* Default construction takes SYMTAB as an argument. */
135 function_summary (symbol_table
*symtab
, bool ggc
= false CXX_MEM_STAT_INFO
);
138 virtual ~function_summary ();
140 /* Traverses all summarys with a function F called with
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
)
153 T
**v
= &m_map
.get_or_insert (node
->get_uid (), &existed
);
155 *v
= this->allocate_new ();
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
);
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
,
197 /* Indication if we use ggc summary. */
201 /* Indication if we use ggc summary. */
202 virtual bool is_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
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
,
227 this->m_symtab_removal_hook
228 = this->m_symtab
->add_cgraph_removal_hook (function_summary::symtab_removal
,
230 this->m_symtab_duplication_hook
231 = this->m_symtab
->add_cgraph_duplication_hook (function_summary::symtab_duplication
,
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
>
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
>
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
>
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
);
275 summary
->duplicate (node
, node2
, v
, summary
->get_create (node2
));
278 template <typename T
>
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
>
288 gt_pch_nx (function_summary
<T
*> *const &)
293 template <typename T
>
295 gt_pch_nx (function_summary
<T
*> *const &, gt_pointer_operator
, void *)
300 /* Help template from std c++11. */
302 template<typename T
, typename U
>
305 static const bool value
= false;
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
317 template <class T
, class V
>
318 class fast_function_summary
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
>
332 /* Default construction takes SYMTAB as an argument. */
333 fast_function_summary (symbol_table
*symtab CXX_MEM_STAT_INFO
);
336 virtual ~fast_function_summary ();
338 /* Traverses all summarys with a function F called with
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 ();
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
)
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 ();
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
,
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
,
425 this->m_symtab_removal_hook
426 = this->m_symtab
->add_cgraph_removal_hook (fast_function_summary::symtab_removal
,
428 this->m_symtab_duplication_hook
429 = this->m_symtab
->add_cgraph_duplication_hook (fast_function_summary::symtab_duplication
,
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
]);
445 template <typename T
, typename V
>
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
>
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
>
469 fast_function_summary
<T
*, V
>::symtab_duplication (cgraph_node
*node
,
473 fast_function_summary
*summary
= (fast_function_summary
<T
*, V
> *) (data
);
474 T
*v
= summary
->get (node
);
478 T
*duplicate
= summary
->get_create (node2
);
479 summary
->duplicate (node
, node2
, v
, duplicate
);
483 template <typename T
, typename V
>
485 fast_function_summary
<T
*, V
>::is_ggc ()
487 return is_same
<V
, va_gc
>::value
;
490 template <typename T
>
492 gt_ggc_mx (fast_function_summary
<T
*, va_heap
>* const &)
496 template <typename T
>
498 gt_pch_nx (fast_function_summary
<T
*, va_heap
>* const &)
502 template <typename T
>
504 gt_pch_nx (fast_function_summary
<T
*, va_heap
>* const&, gt_pointer_operator
,
509 template <typename T
>
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
>
519 gt_pch_nx (fast_function_summary
<T
*, va_gc
> *const &)
524 template <typename T
>
526 gt_pch_nx (fast_function_summary
<T
*, va_gc
> *const &, gt_pointer_operator
,
532 /* Base class for call_summary and fast_call_summary classes. */
535 class call_summary_base
538 /* Default construction takes SYMTAB as an argument. */
539 call_summary_base (symbol_table
*symtab CXX_MEM_STAT_INFO
):
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
*) {}
552 /* Allocates new data that are stored within map. */
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
)
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
;
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
>
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. */
609 /* Class to store auxiliary information about call graph edges. */
612 class GTY((user
)) call_summary
<T
*>: public call_summary_base
<T
>
615 /* Default construction takes SYMTAB as an argument. */
616 call_summary (symbol_table
*symtab
, bool ggc
= false
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
,
624 this->m_symtab_duplication_hook
625 = this->m_symtab
->add_edge_duplication_hook (call_summary::symtab_duplication
,
630 virtual ~call_summary ();
632 /* Traverses all summarys with an edge E called with
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
)
645 T
**v
= &m_map
.get_or_insert (edge
->get_uid (), &existed
);
647 *v
= this->allocate_new ();
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
);
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
,
686 /* Indication if we use ggc summary. */
690 /* Indication if we use ggc summary. */
691 virtual bool is_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
>
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
>
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
);
737 edge1_summary
= summary
->get (edge1
);
740 summary
->duplicate (edge1
, edge2
, edge1_summary
,
741 summary
->get_create (edge2
));
744 template <typename T
>
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
>
754 gt_pch_nx (call_summary
<T
*> *const &)
759 template <typename T
>
761 gt_pch_nx (call_summary
<T
*> *const &, gt_pointer_operator
, void *)
766 /* We want to pass just pointer types as argument for fast_call_summary
769 template <class T
, class V
>
770 class fast_call_summary
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
>
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
,
791 this->m_symtab_duplication_hook
792 = this->m_symtab
->add_edge_duplication_hook (fast_call_summary::symtab_duplication
,
797 virtual ~fast_call_summary ();
799 /* Traverses all summarys with an edge F called with
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 ();
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
)
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 ();
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
,
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
]);
888 template <typename T
, typename V
>
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
>
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
);
907 edge1_summary
= summary
->get (edge1
);
911 T
*duplicate
= summary
->get_create (edge2
);
912 summary
->duplicate (edge1
, edge2
, edge1_summary
, duplicate
);
916 template <typename T
, typename V
>
918 fast_call_summary
<T
*, V
>::is_ggc ()
920 return is_same
<V
, va_gc
>::value
;
923 template <typename T
>
925 gt_ggc_mx (fast_call_summary
<T
*, va_heap
>* const &summary ATTRIBUTE_UNUSED
)
929 template <typename T
>
931 gt_pch_nx (fast_call_summary
<T
*, va_heap
>* const &summary ATTRIBUTE_UNUSED
)
935 template <typename T
>
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
>
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
>
953 gt_pch_nx (fast_call_summary
<T
*, va_gc
> *const &)
958 template <typename T
>
960 gt_pch_nx (fast_call_summary
<T
*, va_gc
> *const &, gt_pointer_operator
, void *)
965 #endif /* GCC_SYMBOL_SUMMARY_H */