* target.def (narrow_volatile_bitfield): Note that the default
[official-gcc.git] / gcc / ipa-devirt.c
blob834cfb01dbb7d68111546e82eb8c40bc5ab31403
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 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 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 specify
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 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 to 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 repsented 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 /* The node of type inheritance graph. For each type unique in
121 One Defintion Rule (ODR) sense, we produce one node linking all
122 main variants of types equivalent to it, bases and derived types. */
124 struct GTY(()) odr_type_d
126 /* Unique ID indexing the type in odr_types array. */
127 int id;
128 /* leader type. */
129 tree type;
130 /* All bases. */
131 vec<odr_type> GTY((skip)) bases;
132 /* All derrived types with virtual methods seen in unit. */
133 vec<odr_type> GTY((skip)) derived_types;
134 /* Is it in anonymous namespace? */
135 bool anonymous_namespace;
139 /* Return true if BINFO corresponds to a type with virtual methods. */
141 static inline bool
142 polymorphic_type_binfo_p (tree binfo)
144 /* See if BINFO's type has an virtual table associtated with it. */
145 return BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (binfo)));
148 /* One Definition Rule hashtable helpers. */
150 struct odr_hasher
152 typedef odr_type_d value_type;
153 typedef union tree_node compare_type;
154 static inline hashval_t hash (const value_type *);
155 static inline bool equal (const value_type *, const compare_type *);
156 static inline void remove (value_type *);
159 /* Produce hash based on type name. */
161 hashval_t
162 hash_type_name (tree t)
164 gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t);
166 /* If not in LTO, all main variants are unique, so we can do
167 pointer hash. */
168 if (!in_lto_p)
169 return htab_hash_pointer (t);
171 /* Anonymous types are unique. */
172 if (type_in_anonymous_namespace_p (t))
173 return htab_hash_pointer (t);
175 /* Rest is not implemented yet. */
176 gcc_unreachable ();
179 /* Return the computed hashcode for ODR_TYPE. */
181 inline hashval_t
182 odr_hasher::hash (const value_type *odr_type)
184 return hash_type_name (odr_type->type);
187 /* Compare types operations T1 and T2 and return true if they are
188 equivalent. */
190 inline bool
191 odr_hasher::equal (const value_type *t1, const compare_type *ct2)
193 tree t2 = const_cast <tree> (ct2);
195 gcc_checking_assert (TYPE_MAIN_VARIANT (ct2) == ct2);
196 if (t1->type == t2)
197 return true;
198 if (!in_lto_p)
199 return false;
200 return types_same_for_odr (t1->type, t2);
203 /* Free a phi operation structure VP. */
205 inline void
206 odr_hasher::remove (value_type *v)
208 v->bases.release ();
209 v->derived_types.release ();
210 ggc_free (v);
213 /* ODR type hash used to lookup ODR type based on tree type node. */
215 typedef hash_table <odr_hasher> odr_hash_type;
216 static odr_hash_type odr_hash;
218 /* ODR types are also stored into ODR_TYPE vector to allow consistent
219 walking. Bases appear before derived types. Vector is garbage collected
220 so we won't end up visiting empty types. */
222 static GTY(()) vec <odr_type, va_gc> *odr_types_ptr;
223 #define odr_types (*odr_types_ptr)
225 /* Get ODR type hash entry for TYPE. If INSERT is true, create
226 possibly new entry. */
228 odr_type
229 get_odr_type (tree type, bool insert)
231 odr_type_d **slot;
232 odr_type val;
233 hashval_t hash;
235 type = TYPE_MAIN_VARIANT (type);
236 gcc_checking_assert (TYPE_MAIN_VARIANT (type) == type);
237 hash = hash_type_name (type);
238 slot = odr_hash.find_slot_with_hash (type, hash, insert ? INSERT : NO_INSERT);
239 if (!slot)
240 return NULL;
242 /* See if we already have entry for type. */
243 if (*slot)
245 val = *slot;
247 /* With LTO we will need to support multiple tree representation of
248 the same ODR type. For now we ignore this. */
249 if (val->type == type)
250 return val;
251 gcc_unreachable ();
253 else
255 tree binfo = TYPE_BINFO (type);
256 unsigned int i;
258 val = ggc_alloc_cleared_odr_type_d ();
259 val->type = type;
260 val->bases = vNULL;
261 val->derived_types = vNULL;
262 *slot = val;
263 for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++)
264 /* For now record only polymorphic types. other are
265 pointless for devirtualization and we can not precisely
266 determine ODR equivalency of these during LTO. */
267 if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (binfo, i)))
269 odr_type base = get_odr_type (BINFO_TYPE (BINFO_BASE_BINFO (binfo,
270 i)),
271 true);
272 base->derived_types.safe_push (val);
273 val->bases.safe_push (base);
275 /* First record bases, then add into array so ids are increasing. */
276 if (odr_types_ptr)
277 val->id = odr_types.length();
278 vec_safe_push (odr_types_ptr, val);
280 return val;
283 /* Dump ODR type T and all its derrived type. INDENT specify indentation for
284 recusive printing. */
286 static void
287 dump_odr_type (FILE *f, odr_type t, int indent=0)
289 unsigned int i;
290 fprintf (f, "%*s type %i: ", indent * 2, "", t->id);
291 print_generic_expr (f, t->type, TDF_SLIM);
292 fprintf (f, "\n");
293 if (TYPE_NAME (t->type))
295 fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "",
296 DECL_SOURCE_FILE (TYPE_NAME (t->type)),
297 DECL_SOURCE_LINE (TYPE_NAME (t->type)));
299 if (t->bases.length())
301 fprintf (f, "%*s base odr type ids: ", indent * 2, "");
302 for (i = 0; i < t->bases.length(); i++)
303 fprintf (f, " %i", t->bases[i]->id);
304 fprintf (f, "\n");
306 if (t->derived_types.length())
308 fprintf (f, "%*s derived types:\n", indent * 2, "");
309 for (i = 0; i < t->derived_types.length(); i++)
310 dump_odr_type (f, t->derived_types[i], indent + 1);
312 fprintf (f, "\n");
315 /* Dump the type inheritance graph. */
317 static void
318 dump_type_inheritance_graph (FILE *f)
320 unsigned int i;
321 fprintf (f, "\n\nType inheritance graph:\n");
322 for (i = 0; i < odr_types.length(); i++)
324 if (odr_types[i]->bases.length() == 0)
325 dump_odr_type (f, odr_types[i]);
329 /* Given method type T, return type of class it belongs to.
330 Lookup this pointer and get its type. */
332 static tree
333 method_class_type (tree t)
335 tree first_parm_type = TREE_VALUE (TYPE_ARG_TYPES (t));
337 return TREE_TYPE (first_parm_type);
340 /* Initialize IPA devirt and build inheritance tree graph. */
342 void
343 build_type_inheritance_graph (void)
345 struct cgraph_node *n;
346 FILE *inheritance_dump_file;
347 int flags;
349 if (odr_hash.is_created ())
350 return;
351 timevar_push (TV_IPA_INHERITANCE);
352 inheritance_dump_file = dump_begin (TDI_inheritance, &flags);
353 odr_hash.create (23);
355 /* We reconstruct the graph starting of types of all methods seen in the
356 the unit. */
357 FOR_EACH_FUNCTION (n)
358 if (DECL_VIRTUAL_P (n->symbol.decl)
359 && symtab_real_symbol_p ((symtab_node)n))
360 get_odr_type (method_class_type (TREE_TYPE (n->symbol.decl)), true);
361 if (inheritance_dump_file)
363 dump_type_inheritance_graph (inheritance_dump_file);
364 dump_end (TDI_inheritance, inheritance_dump_file);
366 timevar_pop (TV_IPA_INHERITANCE);
369 /* If TARGET has associated node, record it in the NODES array. */
371 static void
372 maybe_record_node (vec <cgraph_node *> &nodes,
373 tree target, pointer_set_t *inserted)
375 struct cgraph_node *target_node;
376 enum built_in_function fcode;
378 if (target
379 /* Those are used to mark impossible scenarios. */
380 && (fcode = DECL_FUNCTION_CODE (target))
381 != BUILT_IN_UNREACHABLE
382 && fcode != BUILT_IN_TRAP
383 && !pointer_set_insert (inserted, target)
384 && (target_node = cgraph_get_node (target)) != NULL
385 && symtab_real_symbol_p ((symtab_node)target_node))
386 nodes.safe_push (target_node);
389 /* See if BINFO's type match OTR_TYPE. If so, lookup method
390 in vtable of TYPE_BINFO and insert method to NODES array.
391 Otherwise recurse to base BINFOs.
392 This match what get_binfo_at_offset does, but with offset
393 being unknown.
395 TYPE_BINFO is binfo holding an virtual table matching
396 BINFO's type. In the case of single inheritance, this
397 is binfo of BINFO's type ancestor (vtable is shared),
398 otherwise it is binfo of BINFO's type.
400 MATCHED_VTABLES tracks virtual tables we already did lookup
401 for virtual function in.
404 static void
405 record_binfo (vec <cgraph_node *> &nodes,
406 tree binfo,
407 tree otr_type,
408 tree type_binfo,
409 HOST_WIDE_INT otr_token,
410 pointer_set_t *inserted,
411 pointer_set_t *matched_vtables)
413 tree type = BINFO_TYPE (binfo);
414 int i;
415 tree base_binfo;
417 gcc_checking_assert (BINFO_VTABLE (type_binfo));
419 if (types_same_for_odr (type, otr_type)
420 && !pointer_set_insert (matched_vtables, BINFO_VTABLE (type_binfo)))
422 tree target = gimple_get_virt_method_for_binfo (otr_token, type_binfo);
423 if (target)
424 maybe_record_node (nodes, target, inserted);
425 return;
428 /* Walk bases. */
429 for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
430 /* Walking bases that have no virtual method is pointless excercise. */
431 if (polymorphic_type_binfo_p (base_binfo))
432 record_binfo (nodes, base_binfo, otr_type,
433 BINFO_VTABLE (base_binfo) ? base_binfo : type_binfo,
434 otr_token, inserted,
435 matched_vtables);
438 /* Lookup virtual methods matching OTR_TYPE (with OFFSET and OTR_TOKEN)
439 of TYPE, insert them to NODES, recurse into derived nodes.
440 INSERTED is used to avoid duplicate insertions of methods into NODES.
441 MATCHED_VTABLES are used to avoid duplicate walking vtables. */
443 static void
444 possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes,
445 pointer_set_t *inserted,
446 pointer_set_t *matched_vtables,
447 tree otr_type,
448 odr_type type,
449 HOST_WIDE_INT otr_token)
451 tree binfo = TYPE_BINFO (type->type);
452 unsigned int i;
454 record_binfo (nodes, binfo, otr_type, binfo, otr_token, inserted,
455 matched_vtables);
456 for (i = 0; i < type->derived_types.length(); i++)
457 possible_polymorphic_call_targets_1 (nodes, inserted,
458 matched_vtables,
459 otr_type,
460 type->derived_types[i],
461 otr_token);
464 /* Cache of queries for polymorphic call targets.
466 Enumerating all call targets may get expensive when there are many
467 polymorphic calls in the program, so we memoize all the previous
468 queries and avoid duplicated work. */
470 struct polymorphic_call_target_d
472 odr_type type;
473 HOST_WIDE_INT otr_token;
474 vec <cgraph_node *> targets;
477 /* Polymorphic call target cache helpers. */
479 struct polymorphic_call_target_hasher
481 typedef polymorphic_call_target_d value_type;
482 typedef polymorphic_call_target_d compare_type;
483 static inline hashval_t hash (const value_type *);
484 static inline bool equal (const value_type *, const compare_type *);
485 static inline void remove (value_type *);
488 /* Return the computed hashcode for ODR_QUERY. */
490 inline hashval_t
491 polymorphic_call_target_hasher::hash (const value_type *odr_query)
493 return iterative_hash_hashval_t (odr_query->type->id,
494 odr_query->otr_token);
497 /* Compare cache entries T1 and T2. */
499 inline bool
500 polymorphic_call_target_hasher::equal (const value_type *t1,
501 const compare_type *t2)
503 return t1->type == t2->type && t1->otr_token == t2->otr_token;
506 /* Remove entry in polymorphic call target cache hash. */
508 inline void
509 polymorphic_call_target_hasher::remove (value_type *v)
511 v->targets.release ();
512 free (v);
515 /* Polymorphic call target query cache. */
517 typedef hash_table <polymorphic_call_target_hasher>
518 polymorphic_call_target_hash_type;
519 static polymorphic_call_target_hash_type polymorphic_call_target_hash;
520 pointer_set_t *cached_polymorphic_call_targets;
522 /* Destroy polymorphic call target query cache. */
524 static void
525 free_polymorphic_call_targets_hash ()
527 polymorphic_call_target_hash.dispose ();
528 pointer_set_destroy (cached_polymorphic_call_targets);
529 cached_polymorphic_call_targets = NULL;
532 /* When virtual function is removed, we may need to flush the cache. */
534 static void
535 devirt_node_removal_hook (struct cgraph_node *n, void *d ATTRIBUTE_UNUSED)
537 if (pointer_set_contains (cached_polymorphic_call_targets, n))
538 free_polymorphic_call_targets_hash ();
541 /* Return vector containing possible targets of polymorphic call of type
542 OTR_TYPE caling method OTR_TOKEN with OFFSET. If FINALp is non-NULL,
543 store true if the list is complette.
544 CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry
545 in the target cache. If user needs to visit every target list
546 just once, it can memoize them.
548 Returned vector is placed into cache. It is NOT caller's responsibility
549 to free it. The vector can be freed on cgraph_remove_node call if
550 the particular node is a virtual function present in the cache. */
552 vec <cgraph_node *>
553 possible_polymorphic_call_targets (tree otr_type,
554 HOST_WIDE_INT otr_token,
555 bool *finalp,
556 void **cache_token)
558 static struct cgraph_node_hook_list *node_removal_hook_holder;
559 pointer_set_t *inserted;
560 pointer_set_t *matched_vtables;
561 vec <cgraph_node *> nodes=vNULL;
562 odr_type type;
563 polymorphic_call_target_d key;
564 polymorphic_call_target_d **slot;
565 unsigned int i;
566 tree binfo, target;
568 if (finalp)
569 *finalp = false;
571 type = get_odr_type (otr_type, false);
572 /* If we do not have type in our hash it means we never seen any method
573 in it. */
574 if (!type)
575 return nodes;
577 /* For anonymous namespace types we can attempt to build full type.
578 All derivations must be in this unit. */
579 if (type->anonymous_namespace && finalp && !flag_ltrans)
580 *finalp = true;
582 /* Initialize query cache. */
583 if (!cached_polymorphic_call_targets)
585 cached_polymorphic_call_targets = pointer_set_create ();
586 polymorphic_call_target_hash.create (23);
587 if (!node_removal_hook_holder)
588 node_removal_hook_holder =
589 cgraph_add_node_removal_hook (&devirt_node_removal_hook, NULL);
592 /* Lookup cached answer. */
593 key.type = type;
594 key.otr_token = otr_token;
595 slot = polymorphic_call_target_hash.find_slot (&key, INSERT);
596 if (cache_token)
597 *cache_token = (void *)*slot;
598 if (*slot)
599 return (*slot)->targets;
601 /* Do actual search. */
602 timevar_push (TV_IPA_VIRTUAL_CALL);
603 *slot = XCNEW (polymorphic_call_target_d);
604 if (cache_token)
605 *cache_token = (void *)*slot;
606 (*slot)->type = type;
607 (*slot)->otr_token = otr_token;
609 inserted = pointer_set_create ();
610 matched_vtables = pointer_set_create ();
612 /* First see virtual method of type itself. */
614 binfo = TYPE_BINFO (type->type);
615 target = gimple_get_virt_method_for_binfo (otr_token, binfo);
616 if (target)
617 maybe_record_node (nodes, target, inserted);
618 pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo));
620 /* TODO: If method is final, we can stop here and signaize that
621 list is final. We need C++ FE to pass our info about final
622 methods and classes. */
624 /* Walk recursively all derived types. Here we need to lookup proper basetype
625 via their BINFO walk that is done by record_binfo */
626 for (i = 0; i < type->derived_types.length(); i++)
627 possible_polymorphic_call_targets_1 (nodes, inserted,
628 matched_vtables,
629 otr_type, type->derived_types[i],
630 otr_token);
631 (*slot)->targets = nodes;
633 pointer_set_destroy (inserted);
634 pointer_set_destroy (matched_vtables);
635 timevar_pop (TV_IPA_VIRTUAL_CALL);
636 return nodes;
639 /* Dump all possible targets of a polymorphic call. */
641 void
642 dump_possible_polymorphic_call_targets (FILE *f,
643 tree otr_type,
644 HOST_WIDE_INT otr_token)
646 vec <cgraph_node *> targets;
647 bool final;
648 odr_type type = get_odr_type (otr_type, false);
649 unsigned int i;
651 if (!type)
652 return;
653 targets = possible_polymorphic_call_targets (otr_type, otr_token,
654 &final);
655 fprintf (f, "Targets of polymorphic call of type %i ", type->id);
656 print_generic_expr (f, type->type, TDF_SLIM);
657 fprintf (f, " token %i%s:",
658 (int)otr_token,
659 final ? " (full list)" : " (partial list, may call to other unit)");
660 for (i = 0; i < targets.length (); i++)
661 fprintf (f, " %s/%i", cgraph_node_name (targets[i]),
662 targets[i]->symbol.order);
663 fprintf (f, "\n");
666 #include "gt-ipa-devirt.h"