]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-devirt.c
bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Add -ldl.
[thirdparty/gcc.git] / gcc / ipa-devirt.c
CommitLineData
eefe9a99
JH
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
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
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.
38
39 OTR = OBJ_TYPE_REF
0e1474e5 40 This is the Gimple representation of type information of a polymorphic call.
eefe9a99
JH
41 It contains two parameters:
42 otr_type is a type of class whose method is called.
0e1474e5 43 otr_token is the index into virtual table where address is taken.
eefe9a99
JH
44
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.
49
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.
53
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
0e1474e5 58 virtual table of the base type. Also BINFO_OFFSET specifies
eefe9a99
JH
59 offset of the base within the type.
60
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).
66
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.
71
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
0e1474e5 75 or from DECL_VINDEX of a given virtual table.
eefe9a99
JH
76
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.
81
82 What we do here:
83
84 build_type_inheritance_graph triggers a construction of the type inheritance
85 graph.
86
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
0e1474e5 89 inserted into the graph. Also types without virtual methods are not
eefe9a99
JH
90 represented at all, though it may be easy to add this.
91
92 The inheritance graph is represented as follows:
93
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)
97
0e1474e5 98 Edges are represented by odr_type->base and odr_type->derived_types.
eefe9a99
JH
99 At the moment we do not track offsets of types for multiple inheritance.
100 Adding this is easy.
101
102 possible_polymorphic_call_targets returns, given an parameters found in
103 indirect polymorphic edge all possible polymorphic call targets of the call.
bbc9396b
JH
104
105 pass_ipa_devirt performs simple speculative devirtualization.
eefe9a99
JH
106*/
107
108#include "config.h"
109#include "system.h"
110#include "coretypes.h"
111#include "tm.h"
4d648807 112#include "tree.h"
eefe9a99
JH
113#include "cgraph.h"
114#include "tree-pass.h"
115#include "ggc.h"
116#include "pointer-set.h"
117#include "target.h"
118#include "hash-table.h"
119#include "tree-pretty-print.h"
120#include "ipa-utils.h"
121#include "gimple.h"
bbc9396b 122#include "ipa-inline.h"
61a74079 123#include "diagnostic.h"
68377e53
JH
124#include "tree-dfa.h"
125
126/* Dummy polymorphic call context. */
127
128const ipa_polymorphic_call_context ipa_dummy_polymorphic_call_context
129 = {0, NULL, false, true};
eefe9a99 130
0e1474e5
JH
131/* Pointer set of all call targets appearing in the cache. */
132static pointer_set_t *cached_polymorphic_call_targets;
133
eefe9a99
JH
134/* The node of type inheritance graph. For each type unique in
135 One Defintion Rule (ODR) sense, we produce one node linking all
136 main variants of types equivalent to it, bases and derived types. */
137
138struct GTY(()) odr_type_d
139{
eefe9a99
JH
140 /* leader type. */
141 tree type;
142 /* All bases. */
143 vec<odr_type> GTY((skip)) bases;
144 /* All derrived types with virtual methods seen in unit. */
145 vec<odr_type> GTY((skip)) derived_types;
0e1474e5 146
61a74079
JH
147 /* All equivalent types, if more than one. */
148 vec<tree, va_gc> *types;
149 /* Set of all equivalent types, if NON-NULL. */
150 pointer_set_t * GTY((skip)) types_set;
151
0e1474e5
JH
152 /* Unique ID indexing the type in odr_types array. */
153 int id;
eefe9a99
JH
154 /* Is it in anonymous namespace? */
155 bool anonymous_namespace;
156};
157
158
0e1474e5
JH
159/* Return true if BINFO corresponds to a type with virtual methods.
160
161 Every type has several BINFOs. One is the BINFO associated by the type
162 while other represents bases of derived types. The BINFOs representing
163 bases do not have BINFO_VTABLE pointer set when this is the single
164 inheritance (because vtables are shared). Look up the BINFO of type
165 and check presence of its vtable. */
eefe9a99
JH
166
167static inline bool
168polymorphic_type_binfo_p (tree binfo)
169{
170 /* See if BINFO's type has an virtual table associtated with it. */
171 return BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (binfo)));
172}
173
174/* One Definition Rule hashtable helpers. */
175
176struct odr_hasher
177{
178 typedef odr_type_d value_type;
179 typedef union tree_node compare_type;
180 static inline hashval_t hash (const value_type *);
181 static inline bool equal (const value_type *, const compare_type *);
182 static inline void remove (value_type *);
183};
184
185/* Produce hash based on type name. */
186
187hashval_t
188hash_type_name (tree t)
189{
190 gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t);
191
192 /* If not in LTO, all main variants are unique, so we can do
193 pointer hash. */
194 if (!in_lto_p)
195 return htab_hash_pointer (t);
196
197 /* Anonymous types are unique. */
198 if (type_in_anonymous_namespace_p (t))
199 return htab_hash_pointer (t);
200
61a74079
JH
201 /* For polymorphic types, we can simply hash the virtual table. */
202 if (TYPE_BINFO (t) && BINFO_VTABLE (TYPE_BINFO (t)))
203 {
204 tree v = BINFO_VTABLE (TYPE_BINFO (t));
205 hashval_t hash = 0;
206
207 if (TREE_CODE (v) == POINTER_PLUS_EXPR)
208 {
209 hash = TREE_INT_CST_LOW (TREE_OPERAND (v, 1));
210 v = TREE_OPERAND (TREE_OPERAND (v, 0), 0);
211 }
212
213 v = DECL_ASSEMBLER_NAME (v);
61a74079
JH
214 hash = iterative_hash_hashval_t (hash, htab_hash_pointer (v));
215 return hash;
216 }
217
eefe9a99
JH
218 /* Rest is not implemented yet. */
219 gcc_unreachable ();
220}
221
222/* Return the computed hashcode for ODR_TYPE. */
223
224inline hashval_t
225odr_hasher::hash (const value_type *odr_type)
226{
227 return hash_type_name (odr_type->type);
228}
229
0e1474e5 230/* Compare types T1 and T2 and return true if they are
eefe9a99
JH
231 equivalent. */
232
233inline bool
234odr_hasher::equal (const value_type *t1, const compare_type *ct2)
235{
236 tree t2 = const_cast <tree> (ct2);
237
238 gcc_checking_assert (TYPE_MAIN_VARIANT (ct2) == ct2);
239 if (t1->type == t2)
240 return true;
241 if (!in_lto_p)
242 return false;
243 return types_same_for_odr (t1->type, t2);
244}
245
0e1474e5 246/* Free ODR type V. */
eefe9a99
JH
247
248inline void
249odr_hasher::remove (value_type *v)
250{
251 v->bases.release ();
252 v->derived_types.release ();
61a74079
JH
253 if (v->types_set)
254 pointer_set_destroy (v->types_set);
eefe9a99
JH
255 ggc_free (v);
256}
257
258/* ODR type hash used to lookup ODR type based on tree type node. */
259
260typedef hash_table <odr_hasher> odr_hash_type;
261static odr_hash_type odr_hash;
262
263/* ODR types are also stored into ODR_TYPE vector to allow consistent
264 walking. Bases appear before derived types. Vector is garbage collected
265 so we won't end up visiting empty types. */
266
267static GTY(()) vec <odr_type, va_gc> *odr_types_ptr;
268#define odr_types (*odr_types_ptr)
269
61a74079
JH
270/* TYPE is equivalent to VAL by ODR, but its tree representation differs
271 from VAL->type. This may happen in LTO where tree merging did not merge
272 all variants of the same type. It may or may not mean the ODR violation.
273 Add it to the list of duplicates and warn on some violations. */
274
275static void
276add_type_duplicate (odr_type val, tree type)
277{
278 if (!val->types_set)
279 val->types_set = pointer_set_create ();
280
281 /* See if this duplicate is new. */
282 if (!pointer_set_insert (val->types_set, type))
283 {
284 bool merge = true;
285 bool base_mismatch = false;
286 gcc_assert (in_lto_p);
287 vec_safe_push (val->types, type);
288 unsigned int i,j;
289
290 /* First we compare memory layout. */
291 if (!types_compatible_p (val->type, type))
292 {
293 merge = false;
294 if (BINFO_VTABLE (TYPE_BINFO (val->type))
295 && warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (type)), 0,
296 "type %qD violates one definition rule ",
297 type))
298 inform (DECL_SOURCE_LOCATION (TYPE_NAME (val->type)),
299 "a type with the same name but different layout is "
300 "defined in another translation unit");
61a74079
JH
301 if (cgraph_dump_file)
302 {
303 fprintf (cgraph_dump_file, "ODR violation or merging or ODR type bug?\n");
304
305 print_node (cgraph_dump_file, "", val->type, 0);
306 putc ('\n',cgraph_dump_file);
307 print_node (cgraph_dump_file, "", type, 0);
308 putc ('\n',cgraph_dump_file);
309 }
310 }
311
312 /* Next sanity check that bases are the same. If not, we will end
313 up producing wrong answers. */
314 for (j = 0, i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++)
315 if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (TYPE_BINFO (type), i)))
316 {
317 odr_type base = get_odr_type
318 (BINFO_TYPE
319 (BINFO_BASE_BINFO (TYPE_BINFO (type),
320 i)),
321 true);
322 if (val->bases.length () <= j || val->bases[j] != base)
323 base_mismatch = true;
324 j++;
325 }
326 if (base_mismatch)
327 {
328 merge = false;
329
330 if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (type)), 0,
331 "type %qD violates one definition rule ",
332 type))
333 inform (DECL_SOURCE_LOCATION (TYPE_NAME (val->type)),
334 "a type with the same name but different bases is "
335 "defined in another translation unit");
336 if (cgraph_dump_file)
337 {
338 fprintf (cgraph_dump_file, "ODR bse violation or merging bug?\n");
339
340 print_node (cgraph_dump_file, "", val->type, 0);
341 putc ('\n',cgraph_dump_file);
342 print_node (cgraph_dump_file, "", type, 0);
343 putc ('\n',cgraph_dump_file);
344 }
345 }
346
347 /* Regularize things a little. During LTO same types may come with
348 different BINFOs. Either because their virtual table was
349 not merged by tree merging and only later at decl merging or
350 because one type comes with external vtable, while other
351 with internal. We want to merge equivalent binfos to conserve
352 memory and streaming overhead.
353
354 The external vtables are more harmful: they contain references
355 to external declarations of methods that may be defined in the
356 merged LTO unit. For this reason we absolutely need to remove
357 them and replace by internal variants. Not doing so will lead
358 to incomplete answers from possible_polymorphic_call_targets. */
359 if (!flag_ltrans && merge)
360 {
361 tree master_binfo = TYPE_BINFO (val->type);
362 tree v1 = BINFO_VTABLE (master_binfo);
363 tree v2 = BINFO_VTABLE (TYPE_BINFO (type));
364
365 if (TREE_CODE (v1) == POINTER_PLUS_EXPR)
366 {
367 gcc_assert (TREE_CODE (v2) == POINTER_PLUS_EXPR
368 && operand_equal_p (TREE_OPERAND (v1, 1),
369 TREE_OPERAND (v2, 1), 0));
370 v1 = TREE_OPERAND (TREE_OPERAND (v1, 0), 0);
371 v2 = TREE_OPERAND (TREE_OPERAND (v2, 0), 0);
372 }
373 gcc_assert (DECL_ASSEMBLER_NAME (v1)
374 == DECL_ASSEMBLER_NAME (v2));
375
376 if (DECL_EXTERNAL (v1) && !DECL_EXTERNAL (v2))
377 {
378 unsigned int i;
379
380 TYPE_BINFO (val->type) = TYPE_BINFO (type);
c3284718 381 for (i = 0; i < val->types->length (); i++)
61a74079
JH
382 {
383 if (TYPE_BINFO ((*val->types)[i])
384 == master_binfo)
385 TYPE_BINFO ((*val->types)[i]) = TYPE_BINFO (type);
386 }
387 }
388 else
389 TYPE_BINFO (type) = master_binfo;
390 }
391 }
392}
393
eefe9a99
JH
394/* Get ODR type hash entry for TYPE. If INSERT is true, create
395 possibly new entry. */
396
397odr_type
398get_odr_type (tree type, bool insert)
399{
400 odr_type_d **slot;
401 odr_type val;
402 hashval_t hash;
403
404 type = TYPE_MAIN_VARIANT (type);
405 gcc_checking_assert (TYPE_MAIN_VARIANT (type) == type);
406 hash = hash_type_name (type);
407 slot = odr_hash.find_slot_with_hash (type, hash, insert ? INSERT : NO_INSERT);
408 if (!slot)
409 return NULL;
410
411 /* See if we already have entry for type. */
412 if (*slot)
413 {
414 val = *slot;
415
61a74079
JH
416 /* With LTO we need to support multiple tree representation of
417 the same ODR type. */
418 if (val->type != type)
419 add_type_duplicate (val, type);
eefe9a99
JH
420 }
421 else
422 {
423 tree binfo = TYPE_BINFO (type);
424 unsigned int i;
425
426 val = ggc_alloc_cleared_odr_type_d ();
427 val->type = type;
428 val->bases = vNULL;
429 val->derived_types = vNULL;
0e1474e5 430 val->anonymous_namespace = type_in_anonymous_namespace_p (type);
eefe9a99
JH
431 *slot = val;
432 for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++)
433 /* For now record only polymorphic types. other are
434 pointless for devirtualization and we can not precisely
435 determine ODR equivalency of these during LTO. */
436 if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (binfo, i)))
437 {
438 odr_type base = get_odr_type (BINFO_TYPE (BINFO_BASE_BINFO (binfo,
439 i)),
440 true);
441 base->derived_types.safe_push (val);
442 val->bases.safe_push (base);
443 }
444 /* First record bases, then add into array so ids are increasing. */
445 if (odr_types_ptr)
c3284718 446 val->id = odr_types.length ();
eefe9a99
JH
447 vec_safe_push (odr_types_ptr, val);
448 }
449 return val;
450}
451
452/* Dump ODR type T and all its derrived type. INDENT specify indentation for
453 recusive printing. */
454
455static void
456dump_odr_type (FILE *f, odr_type t, int indent=0)
457{
458 unsigned int i;
459 fprintf (f, "%*s type %i: ", indent * 2, "", t->id);
460 print_generic_expr (f, t->type, TDF_SLIM);
0e1474e5 461 fprintf (f, "%s\n", t->anonymous_namespace ? " (anonymous namespace)":"");
eefe9a99
JH
462 if (TYPE_NAME (t->type))
463 {
464 fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "",
465 DECL_SOURCE_FILE (TYPE_NAME (t->type)),
466 DECL_SOURCE_LINE (TYPE_NAME (t->type)));
467 }
c3284718 468 if (t->bases.length ())
eefe9a99
JH
469 {
470 fprintf (f, "%*s base odr type ids: ", indent * 2, "");
c3284718 471 for (i = 0; i < t->bases.length (); i++)
eefe9a99
JH
472 fprintf (f, " %i", t->bases[i]->id);
473 fprintf (f, "\n");
474 }
c3284718 475 if (t->derived_types.length ())
eefe9a99
JH
476 {
477 fprintf (f, "%*s derived types:\n", indent * 2, "");
c3284718 478 for (i = 0; i < t->derived_types.length (); i++)
eefe9a99
JH
479 dump_odr_type (f, t->derived_types[i], indent + 1);
480 }
481 fprintf (f, "\n");
482}
483
484/* Dump the type inheritance graph. */
485
486static void
487dump_type_inheritance_graph (FILE *f)
488{
489 unsigned int i;
0e1474e5
JH
490 if (!odr_types_ptr)
491 return;
eefe9a99 492 fprintf (f, "\n\nType inheritance graph:\n");
c3284718 493 for (i = 0; i < odr_types.length (); i++)
eefe9a99 494 {
c3284718 495 if (odr_types[i]->bases.length () == 0)
eefe9a99
JH
496 dump_odr_type (f, odr_types[i]);
497 }
c3284718 498 for (i = 0; i < odr_types.length (); i++)
61a74079 499 {
c3284718 500 if (odr_types[i]->types && odr_types[i]->types->length ())
61a74079
JH
501 {
502 unsigned int j;
503 fprintf (f, "Duplicate tree types for odr type %i\n", i);
504 print_node (f, "", odr_types[i]->type, 0);
c3284718 505 for (j = 0; j < odr_types[i]->types->length (); j++)
61a74079
JH
506 {
507 tree t;
508 fprintf (f, "duplicate #%i\n", j);
509 print_node (f, "", (*odr_types[i]->types)[j], 0);
510 t = (*odr_types[i]->types)[j];
511 while (TYPE_P (t) && TYPE_CONTEXT (t))
512 {
513 t = TYPE_CONTEXT (t);
514 print_node (f, "", t, 0);
515 }
516 putc ('\n',f);
517 }
518 }
519 }
eefe9a99
JH
520}
521
522/* Given method type T, return type of class it belongs to.
523 Lookup this pointer and get its type. */
524
64cbf23d 525tree
eefe9a99
JH
526method_class_type (tree t)
527{
528 tree first_parm_type = TREE_VALUE (TYPE_ARG_TYPES (t));
68377e53 529 gcc_assert (TREE_CODE (t) == METHOD_TYPE);
eefe9a99
JH
530
531 return TREE_TYPE (first_parm_type);
532}
533
534/* Initialize IPA devirt and build inheritance tree graph. */
535
536void
537build_type_inheritance_graph (void)
538{
539 struct cgraph_node *n;
540 FILE *inheritance_dump_file;
541 int flags;
542
543 if (odr_hash.is_created ())
544 return;
545 timevar_push (TV_IPA_INHERITANCE);
546 inheritance_dump_file = dump_begin (TDI_inheritance, &flags);
547 odr_hash.create (23);
548
549 /* We reconstruct the graph starting of types of all methods seen in the
550 the unit. */
551 FOR_EACH_FUNCTION (n)
67348ccc
DM
552 if (DECL_VIRTUAL_P (n->decl)
553 && symtab_real_symbol_p (n))
554 get_odr_type (method_class_type (TREE_TYPE (n->decl)), true);
eefe9a99
JH
555 if (inheritance_dump_file)
556 {
557 dump_type_inheritance_graph (inheritance_dump_file);
558 dump_end (TDI_inheritance, inheritance_dump_file);
559 }
560 timevar_pop (TV_IPA_INHERITANCE);
561}
562
68377e53
JH
563/* If TARGET has associated node, record it in the NODES array.
564 if TARGET can not be inserted (for example because its body was
565 already removed and there is no way to refer to it), clear COMPLETEP. */
eefe9a99
JH
566
567static void
568maybe_record_node (vec <cgraph_node *> &nodes,
68377e53
JH
569 tree target, pointer_set_t *inserted,
570 bool *completep)
eefe9a99
JH
571{
572 struct cgraph_node *target_node;
573 enum built_in_function fcode;
574
68377e53 575 if (!target
eefe9a99 576 /* Those are used to mark impossible scenarios. */
68377e53
JH
577 || (fcode = DECL_FUNCTION_CODE (target))
578 == BUILT_IN_UNREACHABLE
579 || fcode == BUILT_IN_TRAP)
580 return;
581
582 target_node = cgraph_get_node (target);
583
584 if (target_node != NULL
3462aa02 585 && (TREE_PUBLIC (target)
67348ccc
DM
586 || target_node->definition)
587 && symtab_real_symbol_p (target_node))
0e1474e5 588 {
68377e53
JH
589 gcc_assert (!target_node->global.inlined_to);
590 gcc_assert (symtab_real_symbol_p (target_node));
591 if (!pointer_set_insert (inserted, target))
592 {
593 pointer_set_insert (cached_polymorphic_call_targets,
594 target_node);
595 nodes.safe_push (target_node);
596 }
0e1474e5 597 }
68377e53
JH
598 else if (completep
599 && !type_in_anonymous_namespace_p
600 (method_class_type (TREE_TYPE (target))))
601 *completep = true;
eefe9a99
JH
602}
603
68377e53
JH
604/* See if BINFO's type match OUTER_TYPE. If so, lookup
605 BINFO of subtype of OTR_TYPE at OFFSET and in that BINFO find
606 method in vtable and insert method to NODES array.
eefe9a99
JH
607 Otherwise recurse to base BINFOs.
608 This match what get_binfo_at_offset does, but with offset
609 being unknown.
610
611 TYPE_BINFO is binfo holding an virtual table matching
612 BINFO's type. In the case of single inheritance, this
613 is binfo of BINFO's type ancestor (vtable is shared),
614 otherwise it is binfo of BINFO's type.
615
616 MATCHED_VTABLES tracks virtual tables we already did lookup
68377e53
JH
617 for virtual function in. INSERTED tracks nodes we already
618 inserted.
3462aa02
JH
619
620 ANONYMOUS is true if BINFO is part of anonymous namespace.
eefe9a99
JH
621 */
622
623static void
68377e53
JH
624record_target_from_binfo (vec <cgraph_node *> &nodes,
625 tree binfo,
626 tree otr_type,
627 tree type_binfo,
628 HOST_WIDE_INT otr_token,
629 tree outer_type,
630 HOST_WIDE_INT offset,
631 pointer_set_t *inserted,
632 pointer_set_t *matched_vtables,
633 bool anonymous)
eefe9a99
JH
634{
635 tree type = BINFO_TYPE (binfo);
636 int i;
637 tree base_binfo;
638
639 gcc_checking_assert (BINFO_VTABLE (type_binfo));
640
68377e53 641 if (types_same_for_odr (type, outer_type))
eefe9a99 642 {
68377e53
JH
643 tree inner_binfo = get_binfo_at_offset (type_binfo,
644 offset, otr_type);
3462aa02
JH
645 /* For types in anonymous namespace first check if the respective vtable
646 is alive. If not, we know the type can't be called. */
647 if (!flag_ltrans && anonymous)
648 {
68377e53 649 tree vtable = BINFO_VTABLE (inner_binfo);
3462aa02
JH
650 struct varpool_node *vnode;
651
652 if (TREE_CODE (vtable) == POINTER_PLUS_EXPR)
653 vtable = TREE_OPERAND (TREE_OPERAND (vtable, 0), 0);
654 vnode = varpool_get_node (vtable);
67348ccc 655 if (!vnode || !vnode->definition)
3462aa02
JH
656 return;
657 }
68377e53
JH
658 gcc_assert (inner_binfo);
659 if (!pointer_set_insert (matched_vtables, BINFO_VTABLE (inner_binfo)))
660 {
661 tree target = gimple_get_virt_method_for_binfo (otr_token, inner_binfo);
662 if (target)
663 maybe_record_node (nodes, target, inserted, NULL);
664 }
eefe9a99
JH
665 return;
666 }
667
668 /* Walk bases. */
669 for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
670 /* Walking bases that have no virtual method is pointless excercise. */
671 if (polymorphic_type_binfo_p (base_binfo))
68377e53
JH
672 record_target_from_binfo (nodes, base_binfo, otr_type,
673 /* In the case of single inheritance,
674 the virtual table is shared with
675 the outer type. */
676 BINFO_VTABLE (base_binfo) ? base_binfo : type_binfo,
677 otr_token, outer_type, offset, inserted,
678 matched_vtables, anonymous);
eefe9a99
JH
679}
680
681/* Lookup virtual methods matching OTR_TYPE (with OFFSET and OTR_TOKEN)
682 of TYPE, insert them to NODES, recurse into derived nodes.
683 INSERTED is used to avoid duplicate insertions of methods into NODES.
684 MATCHED_VTABLES are used to avoid duplicate walking vtables. */
685
686static void
687possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes,
688 pointer_set_t *inserted,
689 pointer_set_t *matched_vtables,
690 tree otr_type,
691 odr_type type,
68377e53
JH
692 HOST_WIDE_INT otr_token,
693 tree outer_type,
694 HOST_WIDE_INT offset)
eefe9a99
JH
695{
696 tree binfo = TYPE_BINFO (type->type);
697 unsigned int i;
698
68377e53
JH
699 record_target_from_binfo (nodes, binfo, otr_type, binfo, otr_token,
700 outer_type, offset,
701 inserted, matched_vtables,
702 type->anonymous_namespace);
c3284718 703 for (i = 0; i < type->derived_types.length (); i++)
eefe9a99
JH
704 possible_polymorphic_call_targets_1 (nodes, inserted,
705 matched_vtables,
706 otr_type,
707 type->derived_types[i],
68377e53 708 otr_token, outer_type, offset);
eefe9a99
JH
709}
710
711/* Cache of queries for polymorphic call targets.
712
713 Enumerating all call targets may get expensive when there are many
714 polymorphic calls in the program, so we memoize all the previous
715 queries and avoid duplicated work. */
716
717struct polymorphic_call_target_d
718{
eefe9a99 719 HOST_WIDE_INT otr_token;
68377e53
JH
720 ipa_polymorphic_call_context context;
721 odr_type type;
eefe9a99 722 vec <cgraph_node *> targets;
68377e53 723 bool final;
eefe9a99
JH
724};
725
726/* Polymorphic call target cache helpers. */
727
728struct polymorphic_call_target_hasher
729{
730 typedef polymorphic_call_target_d value_type;
731 typedef polymorphic_call_target_d compare_type;
732 static inline hashval_t hash (const value_type *);
733 static inline bool equal (const value_type *, const compare_type *);
734 static inline void remove (value_type *);
735};
736
737/* Return the computed hashcode for ODR_QUERY. */
738
739inline hashval_t
740polymorphic_call_target_hasher::hash (const value_type *odr_query)
741{
68377e53
JH
742 hashval_t hash;
743
744 hash = iterative_hash_host_wide_int
745 (odr_query->otr_token,
746 odr_query->type->id);
747 hash = iterative_hash_hashval_t (TYPE_UID (odr_query->context.outer_type),
748 hash);
749 hash = iterative_hash_host_wide_int (odr_query->context.offset, hash);
750 return iterative_hash_hashval_t
751 (((int)odr_query->context.maybe_in_construction << 1)
752 | (int)odr_query->context.maybe_derived_type, hash);
eefe9a99
JH
753}
754
755/* Compare cache entries T1 and T2. */
756
757inline bool
758polymorphic_call_target_hasher::equal (const value_type *t1,
759 const compare_type *t2)
760{
68377e53
JH
761 return (t1->type == t2->type && t1->otr_token == t2->otr_token
762 && t1->context.offset == t2->context.offset
763 && t1->context.outer_type == t2->context.outer_type
764 && t1->context.maybe_in_construction
765 == t2->context.maybe_in_construction
766 && t1->context.maybe_derived_type == t2->context.maybe_derived_type);
eefe9a99
JH
767}
768
769/* Remove entry in polymorphic call target cache hash. */
770
771inline void
772polymorphic_call_target_hasher::remove (value_type *v)
773{
774 v->targets.release ();
775 free (v);
776}
777
778/* Polymorphic call target query cache. */
779
780typedef hash_table <polymorphic_call_target_hasher>
781 polymorphic_call_target_hash_type;
782static polymorphic_call_target_hash_type polymorphic_call_target_hash;
eefe9a99
JH
783
784/* Destroy polymorphic call target query cache. */
785
786static void
787free_polymorphic_call_targets_hash ()
788{
0e1474e5
JH
789 if (cached_polymorphic_call_targets)
790 {
791 polymorphic_call_target_hash.dispose ();
792 pointer_set_destroy (cached_polymorphic_call_targets);
793 cached_polymorphic_call_targets = NULL;
794 }
eefe9a99
JH
795}
796
797/* When virtual function is removed, we may need to flush the cache. */
798
799static void
800devirt_node_removal_hook (struct cgraph_node *n, void *d ATTRIBUTE_UNUSED)
801{
0e1474e5
JH
802 if (cached_polymorphic_call_targets
803 && pointer_set_contains (cached_polymorphic_call_targets, n))
eefe9a99
JH
804 free_polymorphic_call_targets_hash ();
805}
806
68377e53
JH
807/* CONTEXT->OUTER_TYPE is a type of memory object where object of EXPECTED_TYPE
808 is contained at CONTEXT->OFFSET. Walk the memory representation of
809 CONTEXT->OUTER_TYPE and find the outermost class type that match
810 EXPECTED_TYPE or contain EXPECTED_TYPE as a base. Update CONTEXT
811 to represent it.
812
813 For example when CONTEXT represents type
814 class A
815 {
816 int a;
817 class B b;
818 }
819 and we look for type at offset sizeof(int), we end up with B and offset 0.
820 If the same is produced by multiple inheritance, we end up with A and offset
821 sizeof(int).
822
823 If we can not find corresponding class, give up by setting
824 CONTEXT->OUTER_TYPE to EXPECTED_TYPE and CONTEXT->OFFSET to NULL.
825 Return true when lookup was sucesful. */
826
827static bool
828get_class_context (ipa_polymorphic_call_context *context,
829 tree expected_type)
830{
831 tree type = context->outer_type;
832 HOST_WIDE_INT offset = context->offset;
833
834 /* Find the sub-object the constant actually refers to and mark whether it is
835 an artificial one (as opposed to a user-defined one). */
836 while (true)
837 {
838 HOST_WIDE_INT pos, size;
839 tree fld;
840
841 /* On a match, just return what we found. */
842 if (TREE_CODE (type) == TREE_CODE (expected_type)
843 && types_same_for_odr (type, expected_type))
844 {
845 gcc_assert (offset == 0);
846 return true;
847 }
848
849 /* Walk fields and find corresponding on at OFFSET. */
850 if (TREE_CODE (type) == RECORD_TYPE)
851 {
852 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
853 {
854 if (TREE_CODE (fld) != FIELD_DECL)
855 continue;
856
857 pos = int_bit_position (fld);
858 size = tree_to_uhwi (DECL_SIZE (fld));
859 if (pos <= offset && (pos + size) > offset)
860 break;
861 }
862
863 if (!fld)
864 goto give_up;
865
866 type = TREE_TYPE (fld);
867 offset -= pos;
868 /* DECL_ARTIFICIAL represents a basetype. */
869 if (!DECL_ARTIFICIAL (fld))
870 {
871 context->outer_type = type;
872 context->offset = offset;
873 /* As soon as we se an field containing the type,
874 we know we are not looking for derivations. */
875 context->maybe_derived_type = false;
876 }
877 }
878 else if (TREE_CODE (type) == ARRAY_TYPE)
879 {
880 tree subtype = TREE_TYPE (type);
881
882 /* Give up if we don't know array size. */
883 if (!tree_fits_shwi_p (TYPE_SIZE (subtype))
884 || !tree_to_shwi (TYPE_SIZE (subtype)) <= 0)
885 goto give_up;
886 offset = offset % tree_to_shwi (TYPE_SIZE (subtype));
887 type = subtype;
888 context->outer_type = type;
889 context->offset = offset;
890 context->maybe_derived_type = false;
891 }
892 /* Give up on anything else. */
893 else
894 goto give_up;
895 }
896
897 /* If we failed to find subtype we look for, give up and fall back to the
898 most generic query. */
899give_up:
900 context->outer_type = expected_type;
901 context->offset = 0;
902 context->maybe_derived_type = true;
903 return false;
904}
905
906/* Return true if OUTER_TYPE contains OTR_TYPE at OFFSET. */
907
908static bool
909contains_type_p (tree outer_type, HOST_WIDE_INT offset,
910 tree otr_type)
911{
912 ipa_polymorphic_call_context context = {offset, outer_type,
913 false, true};
914 return get_class_context (&context, otr_type);
915}
916
917/* Given REF call in FNDECL, determine class of the polymorphic
918 call (OTR_TYPE), its token (OTR_TOKEN) and CONTEXT.
919 Return pointer to object described by the context */
920
921tree
922get_polymorphic_call_info (tree fndecl,
923 tree ref,
924 tree *otr_type,
925 HOST_WIDE_INT *otr_token,
926 ipa_polymorphic_call_context *context)
927{
928 tree base_pointer;
929 *otr_type = obj_type_ref_class (ref);
930 *otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref));
931
932 /* Set up basic info in case we find nothing interesting in the analysis. */
933 context->outer_type = *otr_type;
934 context->offset = 0;
935 base_pointer = OBJ_TYPE_REF_OBJECT (ref);
936 context->maybe_derived_type = true;
937 context->maybe_in_construction = false;
938
939 /* Walk SSA for outer object. */
940 do
941 {
942 if (TREE_CODE (base_pointer) == SSA_NAME
943 && !SSA_NAME_IS_DEFAULT_DEF (base_pointer)
944 && SSA_NAME_DEF_STMT (base_pointer)
945 && gimple_assign_single_p (SSA_NAME_DEF_STMT (base_pointer)))
946 {
947 base_pointer = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (base_pointer));
948 STRIP_NOPS (base_pointer);
949 }
950 else if (TREE_CODE (base_pointer) == ADDR_EXPR)
951 {
952 HOST_WIDE_INT size, max_size;
953 HOST_WIDE_INT offset2;
954 tree base = get_ref_base_and_extent (TREE_OPERAND (base_pointer, 0),
955 &offset2, &size, &max_size);
956
957 /* If this is a varying address, punt. */
958 if ((TREE_CODE (base) == MEM_REF || DECL_P (base))
959 && max_size != -1
960 && max_size == size)
961 {
962 /* We found dereference of a pointer. Type of the pointer
963 and MEM_REF is meaningless, but we can look futher. */
964 if (TREE_CODE (base) == MEM_REF)
965 {
966 base_pointer = TREE_OPERAND (base, 0);
967 context->offset
968 += offset2 + mem_ref_offset (base).low * BITS_PER_UNIT;
969 context->outer_type = NULL;
970 }
971 /* We found base object. In this case the outer_type
972 is known. */
973 else if (DECL_P (base))
974 {
975 context->outer_type = TREE_TYPE (base);
976 gcc_assert (!POINTER_TYPE_P (context->outer_type));
977
978 /* Only type inconsistent programs can have otr_type that is
979 not part of outer type. */
980 if (!contains_type_p (context->outer_type,
981 context->offset, *otr_type))
982 return base_pointer;
983 context->offset += offset2;
984 base_pointer = NULL;
985 /* Make very conservative assumption that all objects
986 may be in construction.
987 TODO: ipa-prop already contains code to tell better.
988 merge it later. */
989 context->maybe_in_construction = true;
990 context->maybe_derived_type = false;
991 return base_pointer;
992 }
993 else
994 break;
995 }
996 else
997 break;
998 }
999 else if (TREE_CODE (base_pointer) == POINTER_PLUS_EXPR
1000 && tree_fits_uhwi_p (TREE_OPERAND (base_pointer, 1)))
1001 {
1002 context->offset += tree_to_shwi (TREE_OPERAND (base_pointer, 1))
1003 * BITS_PER_UNIT;
1004 base_pointer = TREE_OPERAND (base_pointer, 0);
1005 }
1006 else
1007 break;
1008 }
1009 while (true);
1010
1011 /* Try to determine type of the outer object. */
1012 if (TREE_CODE (base_pointer) == SSA_NAME
1013 && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
1014 && TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL)
1015 {
1016 /* See if parameter is THIS pointer of a method. */
1017 if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE
1018 && SSA_NAME_VAR (base_pointer) == DECL_ARGUMENTS (fndecl))
1019 {
1020 context->outer_type = TREE_TYPE (TREE_TYPE (base_pointer));
1021 gcc_assert (TREE_CODE (context->outer_type) == RECORD_TYPE);
1022
1023 /* Dynamic casting has possibly upcasted the type
1024 in the hiearchy. In this case outer type is less
1025 informative than inner type and we should forget
1026 about it. */
1027 if (!contains_type_p (context->outer_type, context->offset,
1028 *otr_type))
1029 {
1030 context->outer_type = NULL;
1031 return base_pointer;
1032 }
1033
1034 /* If the function is constructor or destructor, then
1035 the type is possibly in consturction, but we know
1036 it is not derived type. */
1037 if (DECL_CXX_CONSTRUCTOR_P (fndecl)
1038 || DECL_CXX_DESTRUCTOR_P (fndecl))
1039 {
1040 context->maybe_in_construction = true;
1041 context->maybe_derived_type = false;
1042 }
1043 else
1044 {
1045 context->maybe_derived_type = true;
1046 context->maybe_in_construction = false;
1047 }
1048 return base_pointer;
1049 }
1050 /* Non-PODs passed by value are really passed by invisible
1051 reference. In this case we also know the type of the
1052 object. */
1053 if (DECL_BY_REFERENCE (SSA_NAME_VAR (base_pointer)))
1054 {
1055 context->outer_type = TREE_TYPE (TREE_TYPE (base_pointer));
1056 gcc_assert (!POINTER_TYPE_P (context->outer_type));
1057 /* Only type inconsistent programs can have otr_type that is
1058 not part of outer type. */
1059 if (!contains_type_p (context->outer_type, context->offset,
1060 *otr_type))
1061 {
1062 context->outer_type = NULL;
1063 gcc_unreachable ();
1064 return base_pointer;
1065 }
1066 context->maybe_derived_type = false;
1067 context->maybe_in_construction = false;
1068 return base_pointer;
1069 }
1070 }
1071 /* TODO: There are multiple ways to derive a type. For instance
1072 if BASE_POINTER is passed to an constructor call prior our refernece.
1073 We do not make this type of flow sensitive analysis yet. */
1074 return base_pointer;
1075}
1076
1077/* Walk bases of OUTER_TYPE that contain OTR_TYPE at OFFSET.
1078 Lookup their respecitve virtual methods for OTR_TOKEN and OTR_TYPE
1079 and insert them to NODES.
1080
1081 MATCHED_VTABLES and INSERTED is used to avoid duplicated work. */
1082
1083static void
1084record_targets_from_bases (tree otr_type,
1085 HOST_WIDE_INT otr_token,
1086 tree outer_type,
1087 HOST_WIDE_INT offset,
1088 vec <cgraph_node *> nodes,
1089 pointer_set_t *inserted,
1090 pointer_set_t *matched_vtables,
1091 bool *completep)
1092{
1093 while (true)
1094 {
1095 HOST_WIDE_INT pos, size;
1096 tree base_binfo;
1097 tree fld;
1098
1099 if (types_same_for_odr (outer_type, otr_type))
1100 return;
1101
1102 for (fld = TYPE_FIELDS (outer_type); fld; fld = DECL_CHAIN (fld))
1103 {
1104 if (TREE_CODE (fld) != FIELD_DECL)
1105 continue;
1106
1107 pos = int_bit_position (fld);
1108 size = tree_to_shwi (DECL_SIZE (fld));
1109 if (pos <= offset && (pos + size) > offset)
1110 break;
1111 }
1112 /* Within a class type we should always find correcponding fields. */
1113 gcc_assert (fld && TREE_CODE (TREE_TYPE (fld)) == RECORD_TYPE);
1114
1115 /* Nonbasetypes should have been stripped by outer_class_type. */
1116 gcc_assert (DECL_ARTIFICIAL (fld));
1117
1118 outer_type = TREE_TYPE (fld);
1119 offset -= pos;
1120
1121 base_binfo = get_binfo_at_offset (TYPE_BINFO (outer_type),
1122 offset, otr_type);
1123 gcc_assert (base_binfo);
1124 if (!pointer_set_insert (matched_vtables, BINFO_VTABLE (base_binfo)))
1125 {
1126 tree target = gimple_get_virt_method_for_binfo (otr_token, base_binfo);
1127 if (target)
1128 maybe_record_node (nodes, target, inserted, completep);
1129 /* The only way method in anonymous namespace can become unreferable
1130 is that it has been fully optimized out. */
1131 else if (flag_ltrans || !type_in_anonymous_namespace_p (outer_type))
1132 *completep = false;
1133 pointer_set_insert (matched_vtables, BINFO_VTABLE (base_binfo));
1134 }
1135 }
1136}
1137
3462aa02
JH
1138/* When virtual table is removed, we may need to flush the cache. */
1139
1140static void
1141devirt_variable_node_removal_hook (struct varpool_node *n,
1142 void *d ATTRIBUTE_UNUSED)
1143{
1144 if (cached_polymorphic_call_targets
67348ccc
DM
1145 && DECL_VIRTUAL_P (n->decl)
1146 && type_in_anonymous_namespace_p (DECL_CONTEXT (n->decl)))
3462aa02
JH
1147 free_polymorphic_call_targets_hash ();
1148}
1149
eefe9a99 1150/* Return vector containing possible targets of polymorphic call of type
68377e53
JH
1151 OTR_TYPE caling method OTR_TOKEN within type of OTR_OUTER_TYPE and OFFSET.
1152 If INCLUDE_BASES is true, walk also base types of OUTER_TYPES containig
1153 OTR_TYPE and include their virtual method. This is useful for types
1154 possibly in construction or destruction where the virtual table may
1155 temporarily change to one of base types. INCLUDE_DERIVER_TYPES make
1156 us to walk the inheritance graph for all derivations.
1157
1158 If COMPLETEP is non-NULL, store true if the list is complette.
eefe9a99
JH
1159 CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry
1160 in the target cache. If user needs to visit every target list
1161 just once, it can memoize them.
1162
1163 Returned vector is placed into cache. It is NOT caller's responsibility
1164 to free it. The vector can be freed on cgraph_remove_node call if
1165 the particular node is a virtual function present in the cache. */
1166
1167vec <cgraph_node *>
1168possible_polymorphic_call_targets (tree otr_type,
1169 HOST_WIDE_INT otr_token,
68377e53
JH
1170 ipa_polymorphic_call_context context,
1171 bool *completep,
eefe9a99
JH
1172 void **cache_token)
1173{
1174 static struct cgraph_node_hook_list *node_removal_hook_holder;
1175 pointer_set_t *inserted;
1176 pointer_set_t *matched_vtables;
1177 vec <cgraph_node *> nodes=vNULL;
68377e53 1178 odr_type type, outer_type;
eefe9a99
JH
1179 polymorphic_call_target_d key;
1180 polymorphic_call_target_d **slot;
1181 unsigned int i;
1182 tree binfo, target;
68377e53 1183 bool final;
eefe9a99 1184
68377e53 1185 type = get_odr_type (otr_type, true);
eefe9a99 1186
68377e53
JH
1187 /* Lookup the outer class type we want to walk. */
1188 if (context.outer_type)
1189 get_class_context (&context, otr_type);
eefe9a99 1190
68377e53
JH
1191 /* We now canonicalize our query, so we do not need extra hashtable entries. */
1192
1193 /* Without outer type, we have no use for offset. Just do the
1194 basic search from innter type */
1195 if (!context.outer_type)
1196 {
1197 context.outer_type = otr_type;
1198 context.offset = 0;
1199 }
1200 /* We need to update our hiearchy if the type does not exist. */
1201 outer_type = get_odr_type (context.outer_type, true);
1202 /* If outer and inner type match, there are no bases to see. */
1203 if (type == outer_type)
1204 context.maybe_in_construction = false;
1205 /* If the type is final, there are no derivations. */
1206 if (TYPE_FINAL_P (outer_type->type))
1207 context.maybe_derived_type = false;
eefe9a99
JH
1208
1209 /* Initialize query cache. */
1210 if (!cached_polymorphic_call_targets)
1211 {
1212 cached_polymorphic_call_targets = pointer_set_create ();
1213 polymorphic_call_target_hash.create (23);
1214 if (!node_removal_hook_holder)
3462aa02
JH
1215 {
1216 node_removal_hook_holder =
1217 cgraph_add_node_removal_hook (&devirt_node_removal_hook, NULL);
1218 varpool_add_node_removal_hook (&devirt_variable_node_removal_hook,
1219 NULL);
1220 }
eefe9a99
JH
1221 }
1222
1223 /* Lookup cached answer. */
1224 key.type = type;
1225 key.otr_token = otr_token;
68377e53 1226 key.context = context;
eefe9a99
JH
1227 slot = polymorphic_call_target_hash.find_slot (&key, INSERT);
1228 if (cache_token)
1229 *cache_token = (void *)*slot;
1230 if (*slot)
68377e53
JH
1231 {
1232 if (completep)
1233 *completep = (*slot)->final;
1234 return (*slot)->targets;
1235 }
1236
1237 final = true;
eefe9a99
JH
1238
1239 /* Do actual search. */
1240 timevar_push (TV_IPA_VIRTUAL_CALL);
1241 *slot = XCNEW (polymorphic_call_target_d);
1242 if (cache_token)
68377e53 1243 *cache_token = (void *)*slot;
eefe9a99
JH
1244 (*slot)->type = type;
1245 (*slot)->otr_token = otr_token;
68377e53 1246 (*slot)->context = context;
eefe9a99
JH
1247
1248 inserted = pointer_set_create ();
1249 matched_vtables = pointer_set_create ();
1250
1251 /* First see virtual method of type itself. */
1252
68377e53
JH
1253 binfo = get_binfo_at_offset (TYPE_BINFO (outer_type->type),
1254 context.offset, otr_type);
eefe9a99
JH
1255 target = gimple_get_virt_method_for_binfo (otr_token, binfo);
1256 if (target)
68377e53
JH
1257 {
1258 maybe_record_node (nodes, target, inserted, &final);
1259
1260 /* In the case we get final method, we don't need
1261 to walk derivations. */
1262 if (DECL_FINAL_P (target))
1263 context.maybe_derived_type = false;
1264 }
1265 /* The only way method in anonymous namespace can become unreferable
1266 is that it has been fully optimized out. */
1267 else if (flag_ltrans || !type->anonymous_namespace)
1268 final = false;
eefe9a99
JH
1269 pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo));
1270
68377e53
JH
1271 /* Next walk bases, if asked to. */
1272 if (context.maybe_in_construction)
1273 record_targets_from_bases (otr_type, otr_token, outer_type->type,
1274 context.offset, nodes, inserted,
1275 matched_vtables, &final);
eefe9a99 1276
68377e53
JH
1277 /* Finally walk recursively all derived types. */
1278 if (context.maybe_derived_type)
1279 {
1280 /* For anonymous namespace types we can attempt to build full type.
1281 All derivations must be in this unit (unless we see partial unit). */
1282 if (!type->anonymous_namespace || flag_ltrans)
1283 final = false;
1284 for (i = 0; i < outer_type->derived_types.length(); i++)
1285 possible_polymorphic_call_targets_1 (nodes, inserted,
1286 matched_vtables,
1287 otr_type, outer_type->derived_types[i],
1288 otr_token, outer_type->type,
1289 context.offset);
1290 }
eefe9a99 1291 (*slot)->targets = nodes;
68377e53
JH
1292 (*slot)->final = final;
1293 if (completep)
1294 *completep = final;
eefe9a99
JH
1295
1296 pointer_set_destroy (inserted);
1297 pointer_set_destroy (matched_vtables);
1298 timevar_pop (TV_IPA_VIRTUAL_CALL);
1299 return nodes;
1300}
1301
1302/* Dump all possible targets of a polymorphic call. */
1303
1304void
1305dump_possible_polymorphic_call_targets (FILE *f,
68377e53
JH
1306 tree otr_type,
1307 HOST_WIDE_INT otr_token,
1308 const ipa_polymorphic_call_context &ctx)
eefe9a99
JH
1309{
1310 vec <cgraph_node *> targets;
1311 bool final;
1312 odr_type type = get_odr_type (otr_type, false);
1313 unsigned int i;
1314
1315 if (!type)
1316 return;
1317 targets = possible_polymorphic_call_targets (otr_type, otr_token,
68377e53 1318 ctx,
eefe9a99 1319 &final);
68377e53 1320 fprintf (f, " Targets of polymorphic call of type %i:", type->id);
eefe9a99 1321 print_generic_expr (f, type->type, TDF_SLIM);
68377e53
JH
1322 fprintf (f, " token %i\n"
1323 " Contained in type:",
1324 (int)otr_token);
1325 print_generic_expr (f, ctx.outer_type, TDF_SLIM);
1326 fprintf (f, " at offset "HOST_WIDE_INT_PRINT_DEC"\n"
1327 " %s%s%s\n ",
1328 ctx.offset,
1329 final ? "This is full list." :
1330 "This is partial list; extra targets may be defined in other units.",
1331 ctx.maybe_in_construction ? " (base types included)" : "",
1332 ctx.maybe_derived_type ? " (derived types included)" : "");
eefe9a99 1333 for (i = 0; i < targets.length (); i++)
fec39fa6 1334 fprintf (f, " %s/%i", targets[i]->name (),
67348ccc 1335 targets[i]->order);
68377e53 1336 fprintf (f, "\n\n");
eefe9a99
JH
1337}
1338
0e1474e5
JH
1339
1340/* Return true if N can be possibly target of a polymorphic call of
1341 OTR_TYPE/OTR_TOKEN. */
1342
1343bool
1344possible_polymorphic_call_target_p (tree otr_type,
1345 HOST_WIDE_INT otr_token,
68377e53 1346 const ipa_polymorphic_call_context &ctx,
0e1474e5
JH
1347 struct cgraph_node *n)
1348{
1349 vec <cgraph_node *> targets;
1350 unsigned int i;
68377e53 1351 enum built_in_function fcode;
450ad0cd 1352 bool final;
0e1474e5 1353
68377e53
JH
1354 if (TREE_CODE (TREE_TYPE (n->decl)) == FUNCTION_TYPE
1355 && ((fcode = DECL_FUNCTION_CODE (n->decl))
1356 == BUILT_IN_UNREACHABLE
1357 || fcode == BUILT_IN_TRAP))
1358 return true;
1359
0e1474e5
JH
1360 if (!odr_hash.is_created ())
1361 return true;
68377e53 1362 targets = possible_polymorphic_call_targets (otr_type, otr_token, ctx, &final);
0e1474e5 1363 for (i = 0; i < targets.length (); i++)
68377e53 1364 if (symtab_semantically_equivalent_p (n, targets[i]))
0e1474e5 1365 return true;
450ad0cd
JH
1366
1367 /* At a moment we allow middle end to dig out new external declarations
1368 as a targets of polymorphic calls. */
67348ccc 1369 if (!final && !n->definition)
450ad0cd 1370 return true;
0e1474e5
JH
1371 return false;
1372}
1373
1374
1375/* After callgraph construction new external nodes may appear.
1376 Add them into the graph. */
1377
1378void
1379update_type_inheritance_graph (void)
1380{
1381 struct cgraph_node *n;
1382
1383 if (!odr_hash.is_created ())
1384 return;
1385 free_polymorphic_call_targets_hash ();
1386 timevar_push (TV_IPA_INHERITANCE);
68377e53 1387 /* We reconstruct the graph starting from types of all methods seen in the
0e1474e5
JH
1388 the unit. */
1389 FOR_EACH_FUNCTION (n)
67348ccc
DM
1390 if (DECL_VIRTUAL_P (n->decl)
1391 && !n->definition
1392 && symtab_real_symbol_p (n))
1393 get_odr_type (method_class_type (TREE_TYPE (n->decl)), true);
0e1474e5
JH
1394 timevar_pop (TV_IPA_INHERITANCE);
1395}
bbc9396b
JH
1396
1397
1398/* Return true if N looks like likely target of a polymorphic call.
1399 Rule out cxa_pure_virtual, noreturns, function declared cold and
1400 other obvious cases. */
1401
1402bool
1403likely_target_p (struct cgraph_node *n)
1404{
1405 int flags;
1406 /* cxa_pure_virtual and similar things are not likely. */
67348ccc 1407 if (TREE_CODE (TREE_TYPE (n->decl)) != METHOD_TYPE)
bbc9396b 1408 return false;
67348ccc 1409 flags = flags_from_decl_or_type (n->decl);
bbc9396b
JH
1410 if (flags & ECF_NORETURN)
1411 return false;
1412 if (lookup_attribute ("cold",
67348ccc 1413 DECL_ATTRIBUTES (n->decl)))
bbc9396b
JH
1414 return false;
1415 if (n->frequency < NODE_FREQUENCY_NORMAL)
1416 return false;
1417 return true;
1418}
1419
1420/* The ipa-devirt pass.
3462aa02
JH
1421 When polymorphic call has only one likely target in the unit,
1422 turn it into speculative call. */
bbc9396b
JH
1423
1424static unsigned int
1425ipa_devirt (void)
1426{
1427 struct cgraph_node *n;
1428 struct pointer_set_t *bad_call_targets = pointer_set_create ();
1429 struct cgraph_edge *e;
1430
1431 int npolymorphic = 0, nspeculated = 0, nconverted = 0, ncold = 0;
1432 int nmultiple = 0, noverwritable = 0, ndevirtualized = 0, nnotdefined = 0;
1433 int nwrong = 0, nok = 0, nexternal = 0;;
1434
1435 FOR_EACH_DEFINED_FUNCTION (n)
1436 {
1437 bool update = false;
1438 if (dump_file && n->indirect_calls)
1439 fprintf (dump_file, "\n\nProcesing function %s/%i\n",
fec39fa6 1440 n->name (), n->order);
bbc9396b
JH
1441 for (e = n->indirect_calls; e; e = e->next_callee)
1442 if (e->indirect_info->polymorphic)
1443 {
1444 struct cgraph_node *likely_target = NULL;
1445 void *cache_token;
1446 bool final;
1447 vec <cgraph_node *>targets
1448 = possible_polymorphic_call_targets
1449 (e, &final, &cache_token);
1450 unsigned int i;
1451
1452 if (dump_file)
1453 dump_possible_polymorphic_call_targets
1454 (dump_file, e);
3462aa02 1455
bbc9396b
JH
1456 npolymorphic++;
1457
bbc9396b
JH
1458 if (!cgraph_maybe_hot_edge_p (e))
1459 {
1460 if (dump_file)
1461 fprintf (dump_file, "Call is cold\n");
1462 ncold++;
1463 continue;
1464 }
1465 if (e->speculative)
1466 {
1467 if (dump_file)
1468 fprintf (dump_file, "Call is aready speculated\n");
1469 nspeculated++;
1470
1471 /* When dumping see if we agree with speculation. */
1472 if (!dump_file)
1473 continue;
1474 }
1475 if (pointer_set_contains (bad_call_targets,
1476 cache_token))
1477 {
1478 if (dump_file)
1479 fprintf (dump_file, "Target list is known to be useless\n");
1480 nmultiple++;
1481 continue;
1482 }
c3284718 1483 for (i = 0; i < targets.length (); i++)
bbc9396b
JH
1484 if (likely_target_p (targets[i]))
1485 {
1486 if (likely_target)
1487 {
1488 likely_target = NULL;
1489 if (dump_file)
1490 fprintf (dump_file, "More than one likely target\n");
1491 nmultiple++;
1492 break;
1493 }
1494 likely_target = targets[i];
1495 }
1496 if (!likely_target)
1497 {
1498 pointer_set_insert (bad_call_targets, cache_token);
1499 continue;
1500 }
1501 /* This is reached only when dumping; check if we agree or disagree
1502 with the speculation. */
1503 if (e->speculative)
1504 {
1505 struct cgraph_edge *e2;
1506 struct ipa_ref *ref;
1507 cgraph_speculative_call_info (e, e2, e, ref);
1508 if (cgraph_function_or_thunk_node (e2->callee, NULL)
1509 == cgraph_function_or_thunk_node (likely_target, NULL))
1510 {
1511 fprintf (dump_file, "We agree with speculation\n");
1512 nok++;
1513 }
1514 else
1515 {
1516 fprintf (dump_file, "We disagree with speculation\n");
1517 nwrong++;
1518 }
1519 continue;
1520 }
67348ccc 1521 if (!likely_target->definition)
bbc9396b
JH
1522 {
1523 if (dump_file)
1524 fprintf (dump_file, "Target is not an definition\n");
1525 nnotdefined++;
1526 continue;
1527 }
1528 /* Do not introduce new references to external symbols. While we
1529 can handle these just well, it is common for programs to
1530 incorrectly with headers defining methods they are linked
1531 with. */
67348ccc 1532 if (DECL_EXTERNAL (likely_target->decl))
bbc9396b
JH
1533 {
1534 if (dump_file)
1535 fprintf (dump_file, "Target is external\n");
1536 nexternal++;
1537 continue;
1538 }
1539 if (cgraph_function_body_availability (likely_target)
1540 <= AVAIL_OVERWRITABLE
67348ccc 1541 && symtab_can_be_discarded (likely_target))
bbc9396b
JH
1542 {
1543 if (dump_file)
1544 fprintf (dump_file, "Target is overwritable\n");
1545 noverwritable++;
1546 continue;
1547 }
1548 else
1549 {
1550 if (dump_file)
1551 fprintf (dump_file,
1552 "Speculatively devirtualizing call in %s/%i to %s/%i\n",
fec39fa6
TS
1553 n->name (), n->order,
1554 likely_target->name (),
67348ccc
DM
1555 likely_target->order);
1556 if (!symtab_can_be_discarded (likely_target))
5b79657a
JH
1557 {
1558 cgraph_node *alias;
1559 alias = cgraph (symtab_nonoverwritable_alias
67348ccc 1560 (likely_target));
5b79657a
JH
1561 if (alias)
1562 likely_target = alias;
1563 }
bbc9396b
JH
1564 nconverted++;
1565 update = true;
1566 cgraph_turn_edge_to_speculative
1567 (e, likely_target, e->count * 8 / 10, e->frequency * 8 / 10);
1568 }
1569 }
1570 if (update)
1571 inline_update_overall_summary (n);
1572 }
1573 pointer_set_destroy (bad_call_targets);
1574
1575 if (dump_file)
1576 fprintf (dump_file,
1577 "%i polymorphic calls, %i devirtualized,"
1578 " %i speculatively devirtualized, %i cold\n"
1579 "%i have multiple targets, %i overwritable,"
1580 " %i already speculated (%i agree, %i disagree),"
1581 " %i external, %i not defined\n",
1582 npolymorphic, ndevirtualized, nconverted, ncold,
1583 nmultiple, noverwritable, nspeculated, nok, nwrong,
1584 nexternal, nnotdefined);
1585 return ndevirtualized ? TODO_remove_functions : 0;
1586}
1587
1588/* Gate for IPCP optimization. */
1589
1590static bool
1591gate_ipa_devirt (void)
1592{
5bbcb888 1593 return flag_devirtualize_speculatively && optimize;
bbc9396b
JH
1594}
1595
1596namespace {
1597
1598const pass_data pass_data_ipa_devirt =
1599{
1600 IPA_PASS, /* type */
1601 "devirt", /* name */
1602 OPTGROUP_NONE, /* optinfo_flags */
1603 true, /* has_gate */
1604 true, /* has_execute */
1605 TV_IPA_DEVIRT, /* tv_id */
1606 0, /* properties_required */
1607 0, /* properties_provided */
1608 0, /* properties_destroyed */
1609 0, /* todo_flags_start */
1610 ( TODO_dump_symtab ), /* todo_flags_finish */
1611};
1612
1613class pass_ipa_devirt : public ipa_opt_pass_d
1614{
1615public:
c3284718
RS
1616 pass_ipa_devirt (gcc::context *ctxt)
1617 : ipa_opt_pass_d (pass_data_ipa_devirt, ctxt,
1618 NULL, /* generate_summary */
1619 NULL, /* write_summary */
1620 NULL, /* read_summary */
1621 NULL, /* write_optimization_summary */
1622 NULL, /* read_optimization_summary */
1623 NULL, /* stmt_fixup */
1624 0, /* function_transform_todo_flags_start */
1625 NULL, /* function_transform */
1626 NULL) /* variable_transform */
bbc9396b
JH
1627 {}
1628
1629 /* opt_pass methods: */
1630 bool gate () { return gate_ipa_devirt (); }
1631 unsigned int execute () { return ipa_devirt (); }
1632
1633}; // class pass_ipa_devirt
1634
1635} // anon namespace
1636
1637ipa_opt_pass_d *
1638make_pass_ipa_devirt (gcc::context *ctxt)
1639{
1640 return new pass_ipa_devirt (ctxt);
1641}
1642
eefe9a99 1643#include "gt-ipa-devirt.h"