* ipa-utils.h (method_class_type): Declare.
[official-gcc.git] / gcc / ipa-devirt.c
blob0b678bd750d2344dfd027730c43edb11b76b3085
1 /* Basic IPA utilities for type inheritance graph construction and
2 devirtualization.
3 Copyright (C) 2013 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* Brief vocalburary:
23 ODR = One Definition Rule
24 In short, the ODR states that:
25 1 In any translation unit, a template, type, function, or object can
26 have no more than one definition. Some of these can have any number
27 of declarations. A definition provides an instance.
28 2 In the entire program, an object or non-inline function cannot have
29 more than one definition; if an object or function is used, it must
30 have exactly one definition. You can declare an object or function
31 that is never used, in which case you don't have to provide
32 a definition. In no event can there be more than one definition.
33 3 Some things, like types, templates, and extern inline functions, can
34 be defined in more than one translation unit. For a given entity,
35 each definition must be the same. Non-extern objects and functions
36 in different translation units are different entities, even if their
37 names and types are the same.
39 OTR = OBJ_TYPE_REF
40 This is the Gimple representation of type information of a polymorphic call.
41 It contains two parameters:
42 otr_type is a type of class whose method is called.
43 otr_token is the index into virtual table where address is taken.
45 BINFO
46 This is the type inheritance information attached to each tree
47 RECORD_TYPE by the C++ frotend. It provides information about base
48 types and virtual tables.
50 BINFO is linked to the RECORD_TYPE by TYPE_BINFO.
51 BINFO also links to its type by BINFO_TYPE and to the virtual table by
52 BINFO_VTABLE.
54 Base types of a given type are enumerated by BINFO_BASE_BINFO
55 vector. Members of this vectors are not BINFOs associated
56 with a base type. Rather they are new copies of BINFOs
57 (base BINFOs). Their virtual tables may differ from
58 virtual table of the base type. Also BINFO_OFFSET specifies
59 offset of the base within the type.
61 In the case of single inheritance, the virtual table is shared
62 and BINFO_VTABLE of base BINFO is NULL. In the case of multiple
63 inheritance the individual virtual tables are pointer to by
64 BINFO_VTABLE of base binfos (that differs of BINFO_VTABLE of
65 binfo associated to the base type).
67 BINFO lookup for a given base type and offset can be done by
68 get_binfo_at_offset. It returns proper BINFO whose virtual table
69 can be used for lookup of virtual methods associated with the
70 base type.
72 token
73 This is an index of virtual method in virtual table associated
74 to the type defining it. Token can be looked up from OBJ_TYPE_REF
75 or from DECL_VINDEX of a given virtual table.
77 polymorphic (indirect) call
78 This is callgraph represention of virtual method call. Every
79 polymorphic call contains otr_type and otr_token taken from
80 original OBJ_TYPE_REF at callgraph construction time.
82 What we do here:
84 build_type_inheritance_graph triggers a construction of the type inheritance
85 graph.
87 We reconstruct it based on types of methods we see in the unit.
88 This means that the graph is not complete. Types with no methods are not
89 inserted into the graph. Also types without virtual methods are not
90 represented at all, though it may be easy to add this.
92 The inheritance graph is represented as follows:
94 Vertices are structures odr_type. Every odr_type may correspond
95 to one or more tree type nodes that are equivalent by ODR rule.
96 (the multiple type nodes appear only with linktime optimization)
98 Edges are represented by odr_type->base and odr_type->derived_types.
99 At the moment we do not track offsets of types for multiple inheritance.
100 Adding this is easy.
102 possible_polymorphic_call_targets returns, given an parameters found in
103 indirect polymorphic edge all possible polymorphic call targets of the call.
106 #include "config.h"
107 #include "system.h"
108 #include "coretypes.h"
109 #include "tm.h"
110 #include "cgraph.h"
111 #include "tree-pass.h"
112 #include "ggc.h"
113 #include "pointer-set.h"
114 #include "target.h"
115 #include "hash-table.h"
116 #include "tree-pretty-print.h"
117 #include "ipa-utils.h"
118 #include "gimple.h"
120 /* Pointer set of all call targets appearing in the cache. */
121 static pointer_set_t *cached_polymorphic_call_targets;
123 /* The node of type inheritance graph. For each type unique in
124 One Defintion Rule (ODR) sense, we produce one node linking all
125 main variants of types equivalent to it, bases and derived types. */
127 struct GTY(()) odr_type_d
129 /* leader type. */
130 tree type;
131 /* All bases. */
132 vec<odr_type> GTY((skip)) bases;
133 /* All derrived types with virtual methods seen in unit. */
134 vec<odr_type> GTY((skip)) derived_types;
136 /* Unique ID indexing the type in odr_types array. */
137 int id;
138 /* Is it in anonymous namespace? */
139 bool anonymous_namespace;
143 /* Return true if BINFO corresponds to a type with virtual methods.
145 Every type has several BINFOs. One is the BINFO associated by the type
146 while other represents bases of derived types. The BINFOs representing
147 bases do not have BINFO_VTABLE pointer set when this is the single
148 inheritance (because vtables are shared). Look up the BINFO of type
149 and check presence of its vtable. */
151 static inline bool
152 polymorphic_type_binfo_p (tree binfo)
154 /* See if BINFO's type has an virtual table associtated with it. */
155 return BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (binfo)));
158 /* One Definition Rule hashtable helpers. */
160 struct odr_hasher
162 typedef odr_type_d value_type;
163 typedef union tree_node compare_type;
164 static inline hashval_t hash (const value_type *);
165 static inline bool equal (const value_type *, const compare_type *);
166 static inline void remove (value_type *);
169 /* Produce hash based on type name. */
171 hashval_t
172 hash_type_name (tree t)
174 gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t);
176 /* If not in LTO, all main variants are unique, so we can do
177 pointer hash. */
178 if (!in_lto_p)
179 return htab_hash_pointer (t);
181 /* Anonymous types are unique. */
182 if (type_in_anonymous_namespace_p (t))
183 return htab_hash_pointer (t);
185 /* Rest is not implemented yet. */
186 gcc_unreachable ();
189 /* Return the computed hashcode for ODR_TYPE. */
191 inline hashval_t
192 odr_hasher::hash (const value_type *odr_type)
194 return hash_type_name (odr_type->type);
197 /* Compare types T1 and T2 and return true if they are
198 equivalent. */
200 inline bool
201 odr_hasher::equal (const value_type *t1, const compare_type *ct2)
203 tree t2 = const_cast <tree> (ct2);
205 gcc_checking_assert (TYPE_MAIN_VARIANT (ct2) == ct2);
206 if (t1->type == t2)
207 return true;
208 if (!in_lto_p)
209 return false;
210 return types_same_for_odr (t1->type, t2);
213 /* Free ODR type V. */
215 inline void
216 odr_hasher::remove (value_type *v)
218 v->bases.release ();
219 v->derived_types.release ();
220 ggc_free (v);
223 /* ODR type hash used to lookup ODR type based on tree type node. */
225 typedef hash_table <odr_hasher> odr_hash_type;
226 static odr_hash_type odr_hash;
228 /* ODR types are also stored into ODR_TYPE vector to allow consistent
229 walking. Bases appear before derived types. Vector is garbage collected
230 so we won't end up visiting empty types. */
232 static GTY(()) vec <odr_type, va_gc> *odr_types_ptr;
233 #define odr_types (*odr_types_ptr)
235 /* Get ODR type hash entry for TYPE. If INSERT is true, create
236 possibly new entry. */
238 odr_type
239 get_odr_type (tree type, bool insert)
241 odr_type_d **slot;
242 odr_type val;
243 hashval_t hash;
245 type = TYPE_MAIN_VARIANT (type);
246 gcc_checking_assert (TYPE_MAIN_VARIANT (type) == type);
247 hash = hash_type_name (type);
248 slot = odr_hash.find_slot_with_hash (type, hash, insert ? INSERT : NO_INSERT);
249 if (!slot)
250 return NULL;
252 /* See if we already have entry for type. */
253 if (*slot)
255 val = *slot;
257 /* With LTO we will need to support multiple tree representation of
258 the same ODR type. For now we ignore this. */
259 if (val->type == type)
260 return val;
261 gcc_unreachable ();
263 else
265 tree binfo = TYPE_BINFO (type);
266 unsigned int i;
268 val = ggc_alloc_cleared_odr_type_d ();
269 val->type = type;
270 val->bases = vNULL;
271 val->derived_types = vNULL;
272 val->anonymous_namespace = type_in_anonymous_namespace_p (type);
273 *slot = val;
274 for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++)
275 /* For now record only polymorphic types. other are
276 pointless for devirtualization and we can not precisely
277 determine ODR equivalency of these during LTO. */
278 if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (binfo, i)))
280 odr_type base = get_odr_type (BINFO_TYPE (BINFO_BASE_BINFO (binfo,
281 i)),
282 true);
283 base->derived_types.safe_push (val);
284 val->bases.safe_push (base);
286 /* First record bases, then add into array so ids are increasing. */
287 if (odr_types_ptr)
288 val->id = odr_types.length();
289 vec_safe_push (odr_types_ptr, val);
291 return val;
294 /* Dump ODR type T and all its derrived type. INDENT specify indentation for
295 recusive printing. */
297 static void
298 dump_odr_type (FILE *f, odr_type t, int indent=0)
300 unsigned int i;
301 fprintf (f, "%*s type %i: ", indent * 2, "", t->id);
302 print_generic_expr (f, t->type, TDF_SLIM);
303 fprintf (f, "%s\n", t->anonymous_namespace ? " (anonymous namespace)":"");
304 if (TYPE_NAME (t->type))
306 fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "",
307 DECL_SOURCE_FILE (TYPE_NAME (t->type)),
308 DECL_SOURCE_LINE (TYPE_NAME (t->type)));
310 if (t->bases.length())
312 fprintf (f, "%*s base odr type ids: ", indent * 2, "");
313 for (i = 0; i < t->bases.length(); i++)
314 fprintf (f, " %i", t->bases[i]->id);
315 fprintf (f, "\n");
317 if (t->derived_types.length())
319 fprintf (f, "%*s derived types:\n", indent * 2, "");
320 for (i = 0; i < t->derived_types.length(); i++)
321 dump_odr_type (f, t->derived_types[i], indent + 1);
323 fprintf (f, "\n");
326 /* Dump the type inheritance graph. */
328 static void
329 dump_type_inheritance_graph (FILE *f)
331 unsigned int i;
332 if (!odr_types_ptr)
333 return;
334 fprintf (f, "\n\nType inheritance graph:\n");
335 for (i = 0; i < odr_types.length(); i++)
337 if (odr_types[i]->bases.length() == 0)
338 dump_odr_type (f, odr_types[i]);
342 /* Given method type T, return type of class it belongs to.
343 Lookup this pointer and get its type. */
345 tree
346 method_class_type (tree t)
348 tree first_parm_type = TREE_VALUE (TYPE_ARG_TYPES (t));
350 return TREE_TYPE (first_parm_type);
353 /* Initialize IPA devirt and build inheritance tree graph. */
355 void
356 build_type_inheritance_graph (void)
358 struct cgraph_node *n;
359 FILE *inheritance_dump_file;
360 int flags;
362 if (odr_hash.is_created ())
363 return;
364 timevar_push (TV_IPA_INHERITANCE);
365 inheritance_dump_file = dump_begin (TDI_inheritance, &flags);
366 odr_hash.create (23);
368 /* We reconstruct the graph starting of types of all methods seen in the
369 the unit. */
370 FOR_EACH_FUNCTION (n)
371 if (DECL_VIRTUAL_P (n->symbol.decl)
372 && symtab_real_symbol_p ((symtab_node)n))
373 get_odr_type (method_class_type (TREE_TYPE (n->symbol.decl)), true);
374 if (inheritance_dump_file)
376 dump_type_inheritance_graph (inheritance_dump_file);
377 dump_end (TDI_inheritance, inheritance_dump_file);
379 timevar_pop (TV_IPA_INHERITANCE);
382 /* If TARGET has associated node, record it in the NODES array. */
384 static void
385 maybe_record_node (vec <cgraph_node *> &nodes,
386 tree target, pointer_set_t *inserted)
388 struct cgraph_node *target_node;
389 enum built_in_function fcode;
391 if (target
392 /* Those are used to mark impossible scenarios. */
393 && (fcode = DECL_FUNCTION_CODE (target))
394 != BUILT_IN_UNREACHABLE
395 && fcode != BUILT_IN_TRAP
396 && !pointer_set_insert (inserted, target)
397 && (target_node = cgraph_get_node (target)) != NULL
398 && symtab_real_symbol_p ((symtab_node)target_node))
400 pointer_set_insert (cached_polymorphic_call_targets,
401 target_node);
402 nodes.safe_push (target_node);
406 /* See if BINFO's type match OTR_TYPE. If so, lookup method
407 in vtable of TYPE_BINFO and insert method to NODES array.
408 Otherwise recurse to base BINFOs.
409 This match what get_binfo_at_offset does, but with offset
410 being unknown.
412 TYPE_BINFO is binfo holding an virtual table matching
413 BINFO's type. In the case of single inheritance, this
414 is binfo of BINFO's type ancestor (vtable is shared),
415 otherwise it is binfo of BINFO's type.
417 MATCHED_VTABLES tracks virtual tables we already did lookup
418 for virtual function in.
421 static void
422 record_binfo (vec <cgraph_node *> &nodes,
423 tree binfo,
424 tree otr_type,
425 tree type_binfo,
426 HOST_WIDE_INT otr_token,
427 pointer_set_t *inserted,
428 pointer_set_t *matched_vtables)
430 tree type = BINFO_TYPE (binfo);
431 int i;
432 tree base_binfo;
434 gcc_checking_assert (BINFO_VTABLE (type_binfo));
436 if (types_same_for_odr (type, otr_type)
437 && !pointer_set_insert (matched_vtables, BINFO_VTABLE (type_binfo)))
439 tree target = gimple_get_virt_method_for_binfo (otr_token, type_binfo);
440 if (target)
441 maybe_record_node (nodes, target, inserted);
442 return;
445 /* Walk bases. */
446 for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
447 /* Walking bases that have no virtual method is pointless excercise. */
448 if (polymorphic_type_binfo_p (base_binfo))
449 record_binfo (nodes, base_binfo, otr_type,
450 /* In the case of single inheritance, the virtual table
451 is shared with the outer type. */
452 BINFO_VTABLE (base_binfo) ? base_binfo : type_binfo,
453 otr_token, inserted,
454 matched_vtables);
457 /* Lookup virtual methods matching OTR_TYPE (with OFFSET and OTR_TOKEN)
458 of TYPE, insert them to NODES, recurse into derived nodes.
459 INSERTED is used to avoid duplicate insertions of methods into NODES.
460 MATCHED_VTABLES are used to avoid duplicate walking vtables. */
462 static void
463 possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes,
464 pointer_set_t *inserted,
465 pointer_set_t *matched_vtables,
466 tree otr_type,
467 odr_type type,
468 HOST_WIDE_INT otr_token)
470 tree binfo = TYPE_BINFO (type->type);
471 unsigned int i;
473 record_binfo (nodes, binfo, otr_type, binfo, otr_token, inserted,
474 matched_vtables);
475 for (i = 0; i < type->derived_types.length(); i++)
476 possible_polymorphic_call_targets_1 (nodes, inserted,
477 matched_vtables,
478 otr_type,
479 type->derived_types[i],
480 otr_token);
483 /* Cache of queries for polymorphic call targets.
485 Enumerating all call targets may get expensive when there are many
486 polymorphic calls in the program, so we memoize all the previous
487 queries and avoid duplicated work. */
489 struct polymorphic_call_target_d
491 odr_type type;
492 HOST_WIDE_INT otr_token;
493 vec <cgraph_node *> targets;
496 /* Polymorphic call target cache helpers. */
498 struct polymorphic_call_target_hasher
500 typedef polymorphic_call_target_d value_type;
501 typedef polymorphic_call_target_d compare_type;
502 static inline hashval_t hash (const value_type *);
503 static inline bool equal (const value_type *, const compare_type *);
504 static inline void remove (value_type *);
507 /* Return the computed hashcode for ODR_QUERY. */
509 inline hashval_t
510 polymorphic_call_target_hasher::hash (const value_type *odr_query)
512 return iterative_hash_hashval_t (odr_query->type->id,
513 odr_query->otr_token);
516 /* Compare cache entries T1 and T2. */
518 inline bool
519 polymorphic_call_target_hasher::equal (const value_type *t1,
520 const compare_type *t2)
522 return t1->type == t2->type && t1->otr_token == t2->otr_token;
525 /* Remove entry in polymorphic call target cache hash. */
527 inline void
528 polymorphic_call_target_hasher::remove (value_type *v)
530 v->targets.release ();
531 free (v);
534 /* Polymorphic call target query cache. */
536 typedef hash_table <polymorphic_call_target_hasher>
537 polymorphic_call_target_hash_type;
538 static polymorphic_call_target_hash_type polymorphic_call_target_hash;
540 /* Destroy polymorphic call target query cache. */
542 static void
543 free_polymorphic_call_targets_hash ()
545 if (cached_polymorphic_call_targets)
547 polymorphic_call_target_hash.dispose ();
548 pointer_set_destroy (cached_polymorphic_call_targets);
549 cached_polymorphic_call_targets = NULL;
553 /* When virtual function is removed, we may need to flush the cache. */
555 static void
556 devirt_node_removal_hook (struct cgraph_node *n, void *d ATTRIBUTE_UNUSED)
558 if (cached_polymorphic_call_targets
559 && pointer_set_contains (cached_polymorphic_call_targets, n))
560 free_polymorphic_call_targets_hash ();
563 /* Return vector containing possible targets of polymorphic call of type
564 OTR_TYPE caling method OTR_TOKEN with OFFSET. If FINALp is non-NULL,
565 store true if the list is complette.
566 CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry
567 in the target cache. If user needs to visit every target list
568 just once, it can memoize them.
570 Returned vector is placed into cache. It is NOT caller's responsibility
571 to free it. The vector can be freed on cgraph_remove_node call if
572 the particular node is a virtual function present in the cache. */
574 vec <cgraph_node *>
575 possible_polymorphic_call_targets (tree otr_type,
576 HOST_WIDE_INT otr_token,
577 bool *finalp,
578 void **cache_token)
580 static struct cgraph_node_hook_list *node_removal_hook_holder;
581 pointer_set_t *inserted;
582 pointer_set_t *matched_vtables;
583 vec <cgraph_node *> nodes=vNULL;
584 odr_type type;
585 polymorphic_call_target_d key;
586 polymorphic_call_target_d **slot;
587 unsigned int i;
588 tree binfo, target;
590 if (finalp)
591 *finalp = false;
593 type = get_odr_type (otr_type, false);
594 /* If we do not have type in our hash it means we never seen any method
595 in it. */
596 if (!type)
597 return nodes;
599 /* For anonymous namespace types we can attempt to build full type.
600 All derivations must be in this unit. */
601 if (type->anonymous_namespace && finalp && !flag_ltrans)
602 *finalp = true;
604 /* Initialize query cache. */
605 if (!cached_polymorphic_call_targets)
607 cached_polymorphic_call_targets = pointer_set_create ();
608 polymorphic_call_target_hash.create (23);
609 if (!node_removal_hook_holder)
610 node_removal_hook_holder =
611 cgraph_add_node_removal_hook (&devirt_node_removal_hook, NULL);
614 /* Lookup cached answer. */
615 key.type = type;
616 key.otr_token = otr_token;
617 slot = polymorphic_call_target_hash.find_slot (&key, INSERT);
618 if (cache_token)
619 *cache_token = (void *)*slot;
620 if (*slot)
621 return (*slot)->targets;
623 /* Do actual search. */
624 timevar_push (TV_IPA_VIRTUAL_CALL);
625 *slot = XCNEW (polymorphic_call_target_d);
626 if (cache_token)
627 *cache_token = (void *)*slot;
628 (*slot)->type = type;
629 (*slot)->otr_token = otr_token;
631 inserted = pointer_set_create ();
632 matched_vtables = pointer_set_create ();
634 /* First see virtual method of type itself. */
636 binfo = TYPE_BINFO (type->type);
637 target = gimple_get_virt_method_for_binfo (otr_token, binfo);
638 if (target)
639 maybe_record_node (nodes, target, inserted);
640 pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo));
642 /* TODO: If method is final, we can stop here and signaize that
643 list is final. We need C++ FE to pass our info about final
644 methods and classes. */
646 /* Walk recursively all derived types. Here we need to lookup proper basetype
647 via their BINFO walk that is done by record_binfo */
648 for (i = 0; i < type->derived_types.length(); i++)
649 possible_polymorphic_call_targets_1 (nodes, inserted,
650 matched_vtables,
651 otr_type, type->derived_types[i],
652 otr_token);
653 (*slot)->targets = nodes;
655 pointer_set_destroy (inserted);
656 pointer_set_destroy (matched_vtables);
657 timevar_pop (TV_IPA_VIRTUAL_CALL);
658 return nodes;
661 /* Dump all possible targets of a polymorphic call. */
663 void
664 dump_possible_polymorphic_call_targets (FILE *f,
665 tree otr_type,
666 HOST_WIDE_INT otr_token)
668 vec <cgraph_node *> targets;
669 bool final;
670 odr_type type = get_odr_type (otr_type, false);
671 unsigned int i;
673 if (!type)
674 return;
675 targets = possible_polymorphic_call_targets (otr_type, otr_token,
676 &final);
677 fprintf (f, "Targets of polymorphic call of type %i ", type->id);
678 print_generic_expr (f, type->type, TDF_SLIM);
679 fprintf (f, " token %i%s:",
680 (int)otr_token,
681 final ? " (full list)" : " (partial list, may call to other unit)");
682 for (i = 0; i < targets.length (); i++)
683 fprintf (f, " %s/%i", cgraph_node_name (targets[i]),
684 targets[i]->symbol.order);
685 fprintf (f, "\n");
689 /* Return true if N can be possibly target of a polymorphic call of
690 OTR_TYPE/OTR_TOKEN. */
692 bool
693 possible_polymorphic_call_target_p (tree otr_type,
694 HOST_WIDE_INT otr_token,
695 struct cgraph_node *n)
697 vec <cgraph_node *> targets;
698 unsigned int i;
700 if (!odr_hash.is_created ())
701 return true;
702 targets = possible_polymorphic_call_targets (otr_type, otr_token);
703 for (i = 0; i < targets.length (); i++)
704 if (n == targets[i])
705 return true;
706 return false;
710 /* After callgraph construction new external nodes may appear.
711 Add them into the graph. */
713 void
714 update_type_inheritance_graph (void)
716 struct cgraph_node *n;
718 if (!odr_hash.is_created ())
719 return;
720 free_polymorphic_call_targets_hash ();
721 timevar_push (TV_IPA_INHERITANCE);
722 /* We reconstruct the graph starting of types of all methods seen in the
723 the unit. */
724 FOR_EACH_FUNCTION (n)
725 if (DECL_VIRTUAL_P (n->symbol.decl)
726 && !n->symbol.definition
727 && symtab_real_symbol_p ((symtab_node)n))
728 get_odr_type (method_class_type (TREE_TYPE (n->symbol.decl)), true);
729 timevar_pop (TV_IPA_INHERITANCE);
731 #include "gt-ipa-devirt.h"