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