PR c++/64356
[official-gcc.git] / gcc / ipa-polymorphic-call.c
blob369d9382adae46d01512bb1dd26f5165029e25bb
1 /* Analysis of polymorphic call context.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "hash-set.h"
26 #include "machmode.h"
27 #include "vec.h"
28 #include "double-int.h"
29 #include "input.h"
30 #include "alias.h"
31 #include "symtab.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "fold-const.h"
36 #include "print-tree.h"
37 #include "calls.h"
38 #include "expr.h"
39 #include "tree-pass.h"
40 #include "target.h"
41 #include "tree-pretty-print.h"
42 #include "predict.h"
43 #include "basic-block.h"
44 #include "hash-map.h"
45 #include "is-a.h"
46 #include "plugin-api.h"
47 #include "hard-reg-set.h"
48 #include "input.h"
49 #include "function.h"
50 #include "ipa-ref.h"
51 #include "cgraph.h"
52 #include "ipa-utils.h"
53 #include "tree-ssa-alias.h"
54 #include "internal-fn.h"
55 #include "gimple-fold.h"
56 #include "gimple-expr.h"
57 #include "gimple.h"
58 #include "alloc-pool.h"
59 #include "symbol-summary.h"
60 #include "ipa-prop.h"
61 #include "ipa-inline.h"
62 #include "diagnostic.h"
63 #include "tree-dfa.h"
64 #include "demangle.h"
65 #include "dbgcnt.h"
66 #include "gimple-pretty-print.h"
67 #include "stor-layout.h"
68 #include "intl.h"
69 #include "data-streamer.h"
70 #include "lto-streamer.h"
71 #include "streamer-hooks.h"
73 /* Return true when TYPE contains an polymorphic type and thus is interesting
74 for devirtualization machinery. */
76 static bool contains_type_p (tree, HOST_WIDE_INT, tree,
77 bool consider_placement_new = true,
78 bool consider_bases = true);
80 bool
81 contains_polymorphic_type_p (const_tree type)
83 type = TYPE_MAIN_VARIANT (type);
85 if (RECORD_OR_UNION_TYPE_P (type))
87 if (TYPE_BINFO (type)
88 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
89 return true;
90 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
91 if (TREE_CODE (fld) == FIELD_DECL
92 && !DECL_ARTIFICIAL (fld)
93 && contains_polymorphic_type_p (TREE_TYPE (fld)))
94 return true;
95 return false;
97 if (TREE_CODE (type) == ARRAY_TYPE)
98 return contains_polymorphic_type_p (TREE_TYPE (type));
99 return false;
102 /* Return true if it seems valid to use placement new to build EXPECTED_TYPE
103 at possition CUR_OFFSET within TYPE.
105 POD can be changed to an instance of a polymorphic type by
106 placement new. Here we play safe and assume that any
107 non-polymorphic type is POD. */
108 bool
109 possible_placement_new (tree type, tree expected_type,
110 HOST_WIDE_INT cur_offset)
112 return ((TREE_CODE (type) != RECORD_TYPE
113 || !TYPE_BINFO (type)
114 || cur_offset >= POINTER_SIZE
115 || !polymorphic_type_binfo_p (TYPE_BINFO (type)))
116 && (!TYPE_SIZE (type)
117 || !tree_fits_shwi_p (TYPE_SIZE (type))
118 || (cur_offset
119 + (expected_type ? tree_to_uhwi (TYPE_SIZE (expected_type))
120 : POINTER_SIZE)
121 <= tree_to_uhwi (TYPE_SIZE (type)))));
124 /* THIS->OUTER_TYPE is a type of memory object where object of OTR_TYPE
125 is contained at THIS->OFFSET. Walk the memory representation of
126 THIS->OUTER_TYPE and find the outermost class type that match
127 OTR_TYPE or contain OTR_TYPE as a base. Update THIS
128 to represent it.
130 If OTR_TYPE is NULL, just find outermost polymorphic type with
131 virtual table present at possition OFFSET.
133 For example when THIS represents type
134 class A
136 int a;
137 class B b;
139 and we look for type at offset sizeof(int), we end up with B and offset 0.
140 If the same is produced by multiple inheritance, we end up with A and offset
141 sizeof(int).
143 If we can not find corresponding class, give up by setting
144 THIS->OUTER_TYPE to OTR_TYPE and THIS->OFFSET to NULL.
145 Return true when lookup was sucesful.
147 When CONSIDER_PLACEMENT_NEW is false, reject contexts that may be made
148 valid only via alocation of new polymorphic type inside by means
149 of placement new.
151 When CONSIDER_BASES is false, only look for actual fields, not base types
152 of TYPE. */
154 bool
155 ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type,
156 bool consider_placement_new,
157 bool consider_bases)
159 tree type = outer_type;
160 HOST_WIDE_INT cur_offset = offset;
161 bool speculative = false;
162 bool size_unknown = false;
163 unsigned HOST_WIDE_INT otr_type_size = POINTER_SIZE;
165 /* Update OUTER_TYPE to match EXPECTED_TYPE if it is not set. */
166 if (!outer_type)
168 clear_outer_type (otr_type);
169 type = otr_type;
170 cur_offset = 0;
172 /* See if OFFSET points inside OUTER_TYPE. If it does not, we know
173 that the context is either invalid, or the instance type must be
174 derived from OUTER_TYPE.
176 Because the instance type may contain field whose type is of OUTER_TYPE,
177 we can not derive any effective information about it.
179 TODO: In the case we know all derrived types, we can definitely do better
180 here. */
181 else if (TYPE_SIZE (outer_type)
182 && tree_fits_shwi_p (TYPE_SIZE (outer_type))
183 && tree_to_shwi (TYPE_SIZE (outer_type)) >= 0
184 && tree_to_shwi (TYPE_SIZE (outer_type)) <= offset)
186 clear_outer_type (otr_type);
187 type = otr_type;
188 cur_offset = 0;
190 /* If derived type is not allowed, we know that the context is invalid.
191 For dynamic types, we really do not have information about
192 size of the memory location. It is possible that completely
193 different type is stored after outer_type. */
194 if (!maybe_derived_type && !dynamic)
196 clear_speculation ();
197 invalid = true;
198 return false;
202 if (otr_type && TYPE_SIZE (otr_type)
203 && tree_fits_shwi_p (TYPE_SIZE (otr_type)))
204 otr_type_size = tree_to_uhwi (TYPE_SIZE (otr_type));
206 if (!type || offset < 0)
207 goto no_useful_type_info;
209 /* Find the sub-object the constant actually refers to and mark whether it is
210 an artificial one (as opposed to a user-defined one).
212 This loop is performed twice; first time for outer_type and second time
213 for speculative_outer_type. The second run has SPECULATIVE set. */
214 while (true)
216 unsigned HOST_WIDE_INT pos, size;
217 tree fld;
219 /* If we do not know size of TYPE, we need to be more conservative
220 about accepting cases where we can not find EXPECTED_TYPE.
221 Generally the types that do matter here are of constant size.
222 Size_unknown case should be very rare. */
223 if (TYPE_SIZE (type)
224 && tree_fits_shwi_p (TYPE_SIZE (type))
225 && tree_to_shwi (TYPE_SIZE (type)) >= 0)
226 size_unknown = false;
227 else
228 size_unknown = true;
230 /* On a match, just return what we found. */
231 if ((otr_type
232 && types_odr_comparable (type, otr_type)
233 && types_same_for_odr (type, otr_type))
234 || (!otr_type
235 && TREE_CODE (type) == RECORD_TYPE
236 && TYPE_BINFO (type)
237 && polymorphic_type_binfo_p (TYPE_BINFO (type))))
239 if (speculative)
241 /* If we did not match the offset, just give up on speculation. */
242 if (cur_offset != 0
243 /* Also check if speculation did not end up being same as
244 non-speculation. */
245 || (types_must_be_same_for_odr (speculative_outer_type,
246 outer_type)
247 && (maybe_derived_type
248 == speculative_maybe_derived_type)))
249 clear_speculation ();
250 return true;
252 else
254 /* If type is known to be final, do not worry about derived
255 types. Testing it here may help us to avoid speculation. */
256 if (otr_type && TREE_CODE (outer_type) == RECORD_TYPE
257 && (!in_lto_p || odr_type_p (outer_type))
258 && type_known_to_have_no_deriavations_p (outer_type))
259 maybe_derived_type = false;
261 /* Type can not contain itself on an non-zero offset. In that case
262 just give up. Still accept the case where size is now known.
263 Either the second copy may appear past the end of type or within
264 the non-POD buffer located inside the variably sized type
265 itself. */
266 if (cur_offset != 0)
267 goto no_useful_type_info;
268 /* If we determined type precisely or we have no clue on
269 speuclation, we are done. */
270 if (!maybe_derived_type || !speculative_outer_type
271 || !speculation_consistent_p (speculative_outer_type,
272 speculative_offset,
273 speculative_maybe_derived_type,
274 otr_type))
276 clear_speculation ();
277 return true;
279 /* Otherwise look into speculation now. */
280 else
282 speculative = true;
283 type = speculative_outer_type;
284 cur_offset = speculative_offset;
285 continue;
290 /* Walk fields and find corresponding on at OFFSET. */
291 if (TREE_CODE (type) == RECORD_TYPE)
293 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
295 if (TREE_CODE (fld) != FIELD_DECL)
296 continue;
298 pos = int_bit_position (fld);
299 if (pos > (unsigned HOST_WIDE_INT)cur_offset)
300 continue;
302 /* Do not consider vptr itself. Not even for placement new. */
303 if (!pos && DECL_ARTIFICIAL (fld)
304 && POINTER_TYPE_P (TREE_TYPE (fld))
305 && TYPE_BINFO (type)
306 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
307 continue;
309 if (!DECL_SIZE (fld) || !tree_fits_uhwi_p (DECL_SIZE (fld)))
310 goto no_useful_type_info;
311 size = tree_to_uhwi (DECL_SIZE (fld));
313 /* We can always skip types smaller than pointer size:
314 those can not contain a virtual table pointer.
316 Disqualifying fields that are too small to fit OTR_TYPE
317 saves work needed to walk them for no benefit.
318 Because of the way the bases are packed into a class, the
319 field's size may be smaller than type size, so it needs
320 to be done with a care. */
322 if (pos <= (unsigned HOST_WIDE_INT)cur_offset
323 && (pos + size) >= (unsigned HOST_WIDE_INT)cur_offset
324 + POINTER_SIZE
325 && (!otr_type
326 || !TYPE_SIZE (TREE_TYPE (fld))
327 || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (fld)))
328 || (pos + tree_to_uhwi (TYPE_SIZE (TREE_TYPE (fld))))
329 >= cur_offset + otr_type_size))
330 break;
333 if (!fld)
334 goto no_useful_type_info;
336 type = TYPE_MAIN_VARIANT (TREE_TYPE (fld));
337 cur_offset -= pos;
338 /* DECL_ARTIFICIAL represents a basetype. */
339 if (!DECL_ARTIFICIAL (fld))
341 if (!speculative)
343 outer_type = type;
344 offset = cur_offset;
345 /* As soon as we se an field containing the type,
346 we know we are not looking for derivations. */
347 maybe_derived_type = false;
349 else
351 speculative_outer_type = type;
352 speculative_offset = cur_offset;
353 speculative_maybe_derived_type = false;
356 else if (!consider_bases)
357 goto no_useful_type_info;
359 else if (TREE_CODE (type) == ARRAY_TYPE)
361 tree subtype = TYPE_MAIN_VARIANT (TREE_TYPE (type));
363 /* Give up if we don't know array field size.
364 Also give up on non-polymorphic types as they are used
365 as buffers for placement new. */
366 if (!TYPE_SIZE (subtype)
367 || !tree_fits_shwi_p (TYPE_SIZE (subtype))
368 || tree_to_shwi (TYPE_SIZE (subtype)) <= 0
369 || !contains_polymorphic_type_p (subtype))
370 goto no_useful_type_info;
372 HOST_WIDE_INT new_offset = cur_offset % tree_to_shwi (TYPE_SIZE (subtype));
374 /* We may see buffer for placement new. In this case the expected type
375 can be bigger than the subtype. */
376 if (TYPE_SIZE (subtype)
377 && (cur_offset + otr_type_size
378 > tree_to_uhwi (TYPE_SIZE (subtype))))
379 goto no_useful_type_info;
381 cur_offset = new_offset;
382 type = subtype;
383 if (!speculative)
385 outer_type = type;
386 offset = cur_offset;
387 maybe_derived_type = false;
389 else
391 speculative_outer_type = type;
392 speculative_offset = cur_offset;
393 speculative_maybe_derived_type = false;
396 /* Give up on anything else. */
397 else
399 no_useful_type_info:
400 if (maybe_derived_type && !speculative
401 && TREE_CODE (outer_type) == RECORD_TYPE
402 && TREE_CODE (otr_type) == RECORD_TYPE
403 && TYPE_BINFO (otr_type)
404 && !offset
405 && get_binfo_at_offset (TYPE_BINFO (otr_type), 0, outer_type))
407 clear_outer_type (otr_type);
408 if (!speculative_outer_type
409 || !speculation_consistent_p (speculative_outer_type,
410 speculative_offset,
411 speculative_maybe_derived_type,
412 otr_type))
413 clear_speculation ();
414 if (speculative_outer_type)
416 speculative = true;
417 type = speculative_outer_type;
418 cur_offset = speculative_offset;
420 else
421 return true;
423 /* We found no way to embedd EXPECTED_TYPE in TYPE.
424 We still permit two special cases - placement new and
425 the case of variadic types containing themselves. */
426 if (!speculative
427 && consider_placement_new
428 && (size_unknown || !type || maybe_derived_type
429 || possible_placement_new (type, otr_type, cur_offset)))
431 /* In these weird cases we want to accept the context.
432 In non-speculative run we have no useful outer_type info
433 (TODO: we may eventually want to record upper bound on the
434 type size that can be used to prune the walk),
435 but we still want to consider speculation that may
436 give useful info. */
437 if (!speculative)
439 clear_outer_type (otr_type);
440 if (!speculative_outer_type
441 || !speculation_consistent_p (speculative_outer_type,
442 speculative_offset,
443 speculative_maybe_derived_type,
444 otr_type))
445 clear_speculation ();
446 if (speculative_outer_type)
448 speculative = true;
449 type = speculative_outer_type;
450 cur_offset = speculative_offset;
452 else
453 return true;
455 else
456 clear_speculation ();
457 return true;
459 else
461 clear_speculation ();
462 if (speculative)
463 return true;
464 clear_outer_type (otr_type);
465 invalid = true;
466 return false;
472 /* Return true if OUTER_TYPE contains OTR_TYPE at OFFSET.
473 CONSIDER_PLACEMENT_NEW makes function to accept cases where OTR_TYPE can
474 be built within OUTER_TYPE by means of placement new. CONSIDER_BASES makes
475 function to accept cases where OTR_TYPE appears as base of OUTER_TYPE or as
476 base of one of fields of OUTER_TYPE. */
478 static bool
479 contains_type_p (tree outer_type, HOST_WIDE_INT offset,
480 tree otr_type,
481 bool consider_placement_new,
482 bool consider_bases)
484 ipa_polymorphic_call_context context;
486 /* Check that type is within range. */
487 if (offset < 0)
488 return false;
489 if (TYPE_SIZE (outer_type) && TYPE_SIZE (otr_type)
490 && TREE_CODE (outer_type) == INTEGER_CST
491 && TREE_CODE (otr_type) == INTEGER_CST
492 && wi::ltu_p (wi::to_offset (outer_type), (wi::to_offset (otr_type) + offset)))
493 return false;
495 context.offset = offset;
496 context.outer_type = TYPE_MAIN_VARIANT (outer_type);
497 context.maybe_derived_type = false;
498 return context.restrict_to_inner_class (otr_type, consider_placement_new, consider_bases);
502 /* We know that the instance is stored in variable or parameter
503 (not dynamically allocated) and we want to disprove the fact
504 that it may be in construction at invocation of CALL.
506 BASE represents memory location where instance is stored.
507 If BASE is NULL, it is assumed to be global memory.
508 OUTER_TYPE is known type of the instance or NULL if not
509 known.
511 For the variable to be in construction we actually need to
512 be in constructor of corresponding global variable or
513 the inline stack of CALL must contain the constructor.
514 Check this condition. This check works safely only before
515 IPA passes, because inline stacks may become out of date
516 later. */
518 bool
519 decl_maybe_in_construction_p (tree base, tree outer_type,
520 gimple call, tree function)
522 if (outer_type)
523 outer_type = TYPE_MAIN_VARIANT (outer_type);
524 gcc_assert (!base || DECL_P (base));
526 /* After inlining the code unification optimizations may invalidate
527 inline stacks. Also we need to give up on global variables after
528 IPA, because addresses of these may have been propagated to their
529 constructors. */
530 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
531 return true;
533 /* Pure functions can not do any changes on the dynamic type;
534 that require writting to memory. */
535 if ((!base || !auto_var_in_fn_p (base, function))
536 && flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
537 return false;
539 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
540 block = BLOCK_SUPERCONTEXT (block))
541 if (BLOCK_ABSTRACT_ORIGIN (block)
542 && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) == FUNCTION_DECL)
544 tree fn = BLOCK_ABSTRACT_ORIGIN (block);
546 if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
547 || (!DECL_CXX_CONSTRUCTOR_P (fn)
548 && !DECL_CXX_DESTRUCTOR_P (fn)))
550 /* Watch for clones where we constant propagated the first
551 argument (pointer to the instance). */
552 fn = DECL_ABSTRACT_ORIGIN (fn);
553 if (!fn
554 || (base && !is_global_var (base))
555 || TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
556 || (!DECL_CXX_CONSTRUCTOR_P (fn)
557 && !DECL_CXX_DESTRUCTOR_P (fn)))
558 continue;
560 if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
561 continue;
563 tree type = TYPE_MAIN_VARIANT (method_class_type (TREE_TYPE (fn)));
565 if (!outer_type || !types_odr_comparable (type, outer_type))
567 if (TREE_CODE (type) == RECORD_TYPE
568 && TYPE_BINFO (type)
569 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
570 return true;
572 else if (types_same_for_odr (type, outer_type))
573 return true;
576 if (!base || (TREE_CODE (base) == VAR_DECL && is_global_var (base)))
578 if (TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
579 || (!DECL_CXX_CONSTRUCTOR_P (function)
580 && !DECL_CXX_DESTRUCTOR_P (function)))
582 if (!DECL_ABSTRACT_ORIGIN (function))
583 return false;
584 /* Watch for clones where we constant propagated the first
585 argument (pointer to the instance). */
586 function = DECL_ABSTRACT_ORIGIN (function);
587 if (!function
588 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
589 || (!DECL_CXX_CONSTRUCTOR_P (function)
590 && !DECL_CXX_DESTRUCTOR_P (function)))
591 return false;
593 tree type = TYPE_MAIN_VARIANT (method_class_type (TREE_TYPE (function)));
594 if (!outer_type || !types_odr_comparable (type, outer_type))
596 if (TREE_CODE (type) == RECORD_TYPE
597 && TYPE_BINFO (type)
598 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
599 return true;
601 else if (types_same_for_odr (type, outer_type))
602 return true;
604 return false;
607 /* Dump human readable context to F. If NEWLINE is true, it will be terminated
608 by a newline. */
610 void
611 ipa_polymorphic_call_context::dump (FILE *f, bool newline) const
613 fprintf (f, " ");
614 if (invalid)
615 fprintf (f, "Call is known to be undefined");
616 else
618 if (useless_p ())
619 fprintf (f, "nothing known");
620 if (outer_type || offset)
622 fprintf (f, "Outer type%s:", dynamic ? " (dynamic)":"");
623 print_generic_expr (f, outer_type, TDF_SLIM);
624 if (maybe_derived_type)
625 fprintf (f, " (or a derived type)");
626 if (maybe_in_construction)
627 fprintf (f, " (maybe in construction)");
628 fprintf (f, " offset "HOST_WIDE_INT_PRINT_DEC,
629 offset);
631 if (speculative_outer_type)
633 if (outer_type || offset)
634 fprintf (f, " ");
635 fprintf (f, "Speculative outer type:");
636 print_generic_expr (f, speculative_outer_type, TDF_SLIM);
637 if (speculative_maybe_derived_type)
638 fprintf (f, " (or a derived type)");
639 fprintf (f, " at offset "HOST_WIDE_INT_PRINT_DEC,
640 speculative_offset);
643 if (newline)
644 fprintf(f, "\n");
647 /* Print context to stderr. */
649 void
650 ipa_polymorphic_call_context::debug () const
652 dump (stderr);
655 /* Stream out the context to OB. */
657 void
658 ipa_polymorphic_call_context::stream_out (struct output_block *ob) const
660 struct bitpack_d bp = bitpack_create (ob->main_stream);
662 bp_pack_value (&bp, invalid, 1);
663 bp_pack_value (&bp, maybe_in_construction, 1);
664 bp_pack_value (&bp, maybe_derived_type, 1);
665 bp_pack_value (&bp, speculative_maybe_derived_type, 1);
666 bp_pack_value (&bp, dynamic, 1);
667 bp_pack_value (&bp, outer_type != NULL, 1);
668 bp_pack_value (&bp, offset != 0, 1);
669 bp_pack_value (&bp, speculative_outer_type != NULL, 1);
670 streamer_write_bitpack (&bp);
672 if (outer_type != NULL)
673 stream_write_tree (ob, outer_type, true);
674 if (offset)
675 streamer_write_hwi (ob, offset);
676 if (speculative_outer_type != NULL)
678 stream_write_tree (ob, speculative_outer_type, true);
679 streamer_write_hwi (ob, speculative_offset);
681 else
682 gcc_assert (!speculative_offset);
685 /* Stream in the context from IB and DATA_IN. */
687 void
688 ipa_polymorphic_call_context::stream_in (struct lto_input_block *ib,
689 struct data_in *data_in)
691 struct bitpack_d bp = streamer_read_bitpack (ib);
693 invalid = bp_unpack_value (&bp, 1);
694 maybe_in_construction = bp_unpack_value (&bp, 1);
695 maybe_derived_type = bp_unpack_value (&bp, 1);
696 speculative_maybe_derived_type = bp_unpack_value (&bp, 1);
697 dynamic = bp_unpack_value (&bp, 1);
698 bool outer_type_p = bp_unpack_value (&bp, 1);
699 bool offset_p = bp_unpack_value (&bp, 1);
700 bool speculative_outer_type_p = bp_unpack_value (&bp, 1);
702 if (outer_type_p)
703 outer_type = stream_read_tree (ib, data_in);
704 else
705 outer_type = NULL;
706 if (offset_p)
707 offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
708 else
709 offset = 0;
710 if (speculative_outer_type_p)
712 speculative_outer_type = stream_read_tree (ib, data_in);
713 speculative_offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
715 else
717 speculative_outer_type = NULL;
718 speculative_offset = 0;
722 /* Proudce polymorphic call context for call method of instance
723 that is located within BASE (that is assumed to be a decl) at offset OFF. */
725 void
726 ipa_polymorphic_call_context::set_by_decl (tree base, HOST_WIDE_INT off)
728 gcc_assert (DECL_P (base));
729 clear_speculation ();
731 if (!contains_polymorphic_type_p (TREE_TYPE (base)))
733 clear_outer_type ();
734 offset = off;
735 return;
737 outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (base));
738 offset = off;
739 /* Make very conservative assumption that all objects
740 may be in construction.
742 It is up to caller to revisit this via
743 get_dynamic_type or decl_maybe_in_construction_p. */
744 maybe_in_construction = true;
745 maybe_derived_type = false;
746 dynamic = false;
749 /* CST is an invariant (address of decl), try to get meaningful
750 polymorphic call context for polymorphic call of method
751 if instance of OTR_TYPE that is located at offset OFF of this invariant.
752 Return FALSE if nothing meaningful can be found. */
754 bool
755 ipa_polymorphic_call_context::set_by_invariant (tree cst,
756 tree otr_type,
757 HOST_WIDE_INT off)
759 HOST_WIDE_INT offset2, size, max_size;
760 tree base;
762 invalid = false;
763 off = 0;
764 clear_outer_type (otr_type);
766 if (TREE_CODE (cst) != ADDR_EXPR)
767 return false;
769 cst = TREE_OPERAND (cst, 0);
770 base = get_ref_base_and_extent (cst, &offset2, &size, &max_size);
771 if (!DECL_P (base) || max_size == -1 || max_size != size)
772 return false;
774 /* Only type inconsistent programs can have otr_type that is
775 not part of outer type. */
776 if (otr_type && !contains_type_p (TREE_TYPE (base), off, otr_type))
777 return false;
779 set_by_decl (base, off);
780 return true;
783 /* See if OP is SSA name initialized as a copy or by single assignment.
784 If so, walk the SSA graph up. Because simple PHI conditional is considered
785 copy, GLOBAL_VISITED may be used to avoid infinite loop walking the SSA
786 graph. */
788 static tree
789 walk_ssa_copies (tree op, hash_set<tree> **global_visited = NULL)
791 hash_set <tree> *visited = NULL;
792 STRIP_NOPS (op);
793 while (TREE_CODE (op) == SSA_NAME
794 && !SSA_NAME_IS_DEFAULT_DEF (op)
795 && SSA_NAME_DEF_STMT (op)
796 && (gimple_assign_single_p (SSA_NAME_DEF_STMT (op))
797 || gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI))
799 if (global_visited)
801 if (!*global_visited)
802 *global_visited = new hash_set<tree>;
803 if ((*global_visited)->add (op))
804 goto done;
806 else
808 if (!visited)
809 visited = new hash_set<tree>;
810 if (visited->add (op))
811 goto done;
813 /* Special case
814 if (ptr == 0)
815 ptr = 0;
816 else
817 ptr = ptr.foo;
818 This pattern is implicitly produced for casts to non-primary
819 bases. When doing context analysis, we do not really care
820 about the case pointer is NULL, becuase the call will be
821 undefined anyway. */
822 if (gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI)
824 gimple phi = SSA_NAME_DEF_STMT (op);
826 if (gimple_phi_num_args (phi) > 2)
827 goto done;
828 if (gimple_phi_num_args (phi) == 1)
829 op = gimple_phi_arg_def (phi, 0);
830 else if (integer_zerop (gimple_phi_arg_def (phi, 0)))
831 op = gimple_phi_arg_def (phi, 1);
832 else if (integer_zerop (gimple_phi_arg_def (phi, 1)))
833 op = gimple_phi_arg_def (phi, 0);
834 else
835 goto done;
837 else
839 if (gimple_assign_load_p (SSA_NAME_DEF_STMT (op)))
840 goto done;
841 op = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op));
843 STRIP_NOPS (op);
845 done:
846 if (visited)
847 delete (visited);
848 return op;
851 /* Create polymorphic call context from IP invariant CST.
852 This is typically &global_var.
853 OTR_TYPE specify type of polymorphic call or NULL if unknown, OFF
854 is offset of call. */
856 ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree cst,
857 tree otr_type,
858 HOST_WIDE_INT off)
860 clear_speculation ();
861 set_by_invariant (cst, otr_type, off);
864 /* Build context for pointer REF contained in FNDECL at statement STMT.
865 if INSTANCE is non-NULL, return pointer to the object described by
866 the context or DECL where context is contained in. */
868 ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl,
869 tree ref,
870 gimple stmt,
871 tree *instance)
873 tree otr_type = NULL;
874 tree base_pointer;
875 hash_set <tree> *visited = NULL;
877 if (TREE_CODE (ref) == OBJ_TYPE_REF)
879 otr_type = obj_type_ref_class (ref);
880 base_pointer = OBJ_TYPE_REF_OBJECT (ref);
882 else
883 base_pointer = ref;
885 /* Set up basic info in case we find nothing interesting in the analysis. */
886 clear_speculation ();
887 clear_outer_type (otr_type);
888 invalid = false;
890 /* Walk SSA for outer object. */
891 while (true)
893 base_pointer = walk_ssa_copies (base_pointer, &visited);
894 if (TREE_CODE (base_pointer) == ADDR_EXPR)
896 HOST_WIDE_INT size, max_size;
897 HOST_WIDE_INT offset2;
898 tree base = get_ref_base_and_extent (TREE_OPERAND (base_pointer, 0),
899 &offset2, &size, &max_size);
901 if (max_size != -1 && max_size == size)
902 combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)),
903 offset + offset2,
904 true,
905 NULL /* Do not change outer type. */);
907 /* If this is a varying address, punt. */
908 if ((TREE_CODE (base) == MEM_REF || DECL_P (base))
909 && max_size != -1
910 && max_size == size)
912 /* We found dereference of a pointer. Type of the pointer
913 and MEM_REF is meaningless, but we can look futher. */
914 if (TREE_CODE (base) == MEM_REF)
916 base_pointer = TREE_OPERAND (base, 0);
917 offset
918 += offset2 + mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
919 outer_type = NULL;
921 /* We found base object. In this case the outer_type
922 is known. */
923 else if (DECL_P (base))
925 if (visited)
926 delete (visited);
927 /* Only type inconsistent programs can have otr_type that is
928 not part of outer type. */
929 if (otr_type
930 && !contains_type_p (TREE_TYPE (base),
931 offset + offset2, otr_type))
933 invalid = true;
934 if (instance)
935 *instance = base_pointer;
936 return;
938 set_by_decl (base, offset + offset2);
939 if (outer_type && maybe_in_construction && stmt)
940 maybe_in_construction
941 = decl_maybe_in_construction_p (base,
942 outer_type,
943 stmt,
944 fndecl);
945 if (instance)
946 *instance = base;
947 return;
949 else
950 break;
952 else
953 break;
955 else if (TREE_CODE (base_pointer) == POINTER_PLUS_EXPR
956 && tree_fits_uhwi_p (TREE_OPERAND (base_pointer, 1)))
958 offset += tree_to_shwi (TREE_OPERAND (base_pointer, 1))
959 * BITS_PER_UNIT;
960 base_pointer = TREE_OPERAND (base_pointer, 0);
962 else
963 break;
966 if (visited)
967 delete (visited);
969 /* Try to determine type of the outer object. */
970 if (TREE_CODE (base_pointer) == SSA_NAME
971 && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
972 && TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL)
974 /* See if parameter is THIS pointer of a method. */
975 if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE
976 && SSA_NAME_VAR (base_pointer) == DECL_ARGUMENTS (fndecl))
978 outer_type
979 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
980 gcc_assert (TREE_CODE (outer_type) == RECORD_TYPE
981 || TREE_CODE (outer_type) == UNION_TYPE);
983 /* Dynamic casting has possibly upcasted the type
984 in the hiearchy. In this case outer type is less
985 informative than inner type and we should forget
986 about it. */
987 if ((otr_type
988 && !contains_type_p (outer_type, offset,
989 otr_type))
990 || !contains_polymorphic_type_p (outer_type))
992 outer_type = NULL;
993 if (instance)
994 *instance = base_pointer;
995 return;
998 dynamic = true;
1000 /* If the function is constructor or destructor, then
1001 the type is possibly in construction, but we know
1002 it is not derived type. */
1003 if (DECL_CXX_CONSTRUCTOR_P (fndecl)
1004 || DECL_CXX_DESTRUCTOR_P (fndecl))
1006 maybe_in_construction = true;
1007 maybe_derived_type = false;
1009 else
1011 maybe_derived_type = true;
1012 maybe_in_construction = false;
1014 if (instance)
1015 *instance = base_pointer;
1016 return;
1018 /* Non-PODs passed by value are really passed by invisible
1019 reference. In this case we also know the type of the
1020 object. */
1021 if (DECL_BY_REFERENCE (SSA_NAME_VAR (base_pointer)))
1023 outer_type
1024 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
1025 /* Only type inconsistent programs can have otr_type that is
1026 not part of outer type. */
1027 if (otr_type && !contains_type_p (outer_type, offset,
1028 otr_type))
1030 invalid = true;
1031 if (instance)
1032 *instance = base_pointer;
1033 return;
1035 /* Non-polymorphic types have no interest for us. */
1036 else if (!otr_type && !contains_polymorphic_type_p (outer_type))
1038 outer_type = NULL;
1039 if (instance)
1040 *instance = base_pointer;
1041 return;
1043 maybe_derived_type = false;
1044 maybe_in_construction = false;
1045 if (instance)
1046 *instance = base_pointer;
1047 return;
1051 tree base_type = TREE_TYPE (base_pointer);
1053 if (TREE_CODE (base_pointer) == SSA_NAME
1054 && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
1055 && !(TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL
1056 || TREE_CODE (SSA_NAME_VAR (base_pointer)) == RESULT_DECL))
1058 invalid = true;
1059 if (instance)
1060 *instance = base_pointer;
1061 return;
1063 if (TREE_CODE (base_pointer) == SSA_NAME
1064 && SSA_NAME_DEF_STMT (base_pointer)
1065 && gimple_assign_single_p (SSA_NAME_DEF_STMT (base_pointer)))
1066 base_type = TREE_TYPE (gimple_assign_rhs1
1067 (SSA_NAME_DEF_STMT (base_pointer)));
1069 if (POINTER_TYPE_P (base_type))
1070 combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base_type)),
1071 offset,
1072 true, NULL /* Do not change type here */);
1073 /* TODO: There are multiple ways to derive a type. For instance
1074 if BASE_POINTER is passed to an constructor call prior our refernece.
1075 We do not make this type of flow sensitive analysis yet. */
1076 if (instance)
1077 *instance = base_pointer;
1078 return;
1081 /* Structure to be passed in between detect_type_change and
1082 check_stmt_for_type_change. */
1084 struct type_change_info
1086 /* Offset into the object where there is the virtual method pointer we are
1087 looking for. */
1088 HOST_WIDE_INT offset;
1089 /* The declaration or SSA_NAME pointer of the base that we are checking for
1090 type change. */
1091 tree instance;
1092 /* The reference to virtual table pointer used. */
1093 tree vtbl_ptr_ref;
1094 tree otr_type;
1095 /* If we actually can tell the type that the object has changed to, it is
1096 stored in this field. Otherwise it remains NULL_TREE. */
1097 tree known_current_type;
1098 HOST_WIDE_INT known_current_offset;
1100 /* Set to true if dynamic type change has been detected. */
1101 bool type_maybe_changed;
1102 /* Set to true if multiple types have been encountered. known_current_type
1103 must be disregarded in that case. */
1104 bool multiple_types_encountered;
1105 /* Set to true if we possibly missed some dynamic type changes and we should
1106 consider the set to be speculative. */
1107 bool speculative;
1108 bool seen_unanalyzed_store;
1111 /* Return true if STMT is not call and can modify a virtual method table pointer.
1112 We take advantage of fact that vtable stores must appear within constructor
1113 and destructor functions. */
1115 static bool
1116 noncall_stmt_may_be_vtbl_ptr_store (gimple stmt)
1118 if (is_gimple_assign (stmt))
1120 tree lhs = gimple_assign_lhs (stmt);
1122 if (gimple_clobber_p (stmt))
1123 return false;
1124 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
1126 if (flag_strict_aliasing
1127 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
1128 return false;
1130 if (TREE_CODE (lhs) == COMPONENT_REF
1131 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
1132 return false;
1133 /* In the future we might want to use get_base_ref_and_offset to find
1134 if there is a field corresponding to the offset and if so, proceed
1135 almost like if it was a component ref. */
1139 /* Code unification may mess with inline stacks. */
1140 if (cfun->after_inlining)
1141 return true;
1143 /* Walk the inline stack and watch out for ctors/dtors.
1144 TODO: Maybe we can require the store to appear in toplevel
1145 block of CTOR/DTOR. */
1146 for (tree block = gimple_block (stmt); block && TREE_CODE (block) == BLOCK;
1147 block = BLOCK_SUPERCONTEXT (block))
1148 if (BLOCK_ABSTRACT_ORIGIN (block)
1149 && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) == FUNCTION_DECL)
1151 tree fn = BLOCK_ABSTRACT_ORIGIN (block);
1153 if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
1154 return false;
1155 return (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
1156 && (DECL_CXX_CONSTRUCTOR_P (fn)
1157 || DECL_CXX_DESTRUCTOR_P (fn)));
1159 return (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
1160 && (DECL_CXX_CONSTRUCTOR_P (current_function_decl)
1161 || DECL_CXX_DESTRUCTOR_P (current_function_decl)));
1164 /* If STMT can be proved to be an assignment to the virtual method table
1165 pointer of ANALYZED_OBJ and the type associated with the new table
1166 identified, return the type. Otherwise return NULL_TREE if type changes
1167 in unknown way or ERROR_MARK_NODE if type is unchanged. */
1169 static tree
1170 extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci,
1171 HOST_WIDE_INT *type_offset)
1173 HOST_WIDE_INT offset, size, max_size;
1174 tree lhs, rhs, base;
1176 if (!gimple_assign_single_p (stmt))
1177 return NULL_TREE;
1179 lhs = gimple_assign_lhs (stmt);
1180 rhs = gimple_assign_rhs1 (stmt);
1181 if (TREE_CODE (lhs) != COMPONENT_REF
1182 || !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
1184 if (dump_file)
1185 fprintf (dump_file, " LHS is not virtual table.\n");
1186 return NULL_TREE;
1189 if (tci->vtbl_ptr_ref && operand_equal_p (lhs, tci->vtbl_ptr_ref, 0))
1191 else
1193 base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
1194 if (DECL_P (tci->instance))
1196 if (base != tci->instance)
1198 if (dump_file)
1200 fprintf (dump_file, " base:");
1201 print_generic_expr (dump_file, base, TDF_SLIM);
1202 fprintf (dump_file, " does not match instance:");
1203 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1204 fprintf (dump_file, "\n");
1206 return NULL_TREE;
1209 else if (TREE_CODE (base) == MEM_REF)
1211 if (!operand_equal_p (tci->instance, TREE_OPERAND (base, 0), 0))
1213 if (dump_file)
1215 fprintf (dump_file, " base mem ref:");
1216 print_generic_expr (dump_file, base, TDF_SLIM);
1217 fprintf (dump_file, " does not match instance:");
1218 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1219 fprintf (dump_file, "\n");
1221 return NULL_TREE;
1223 if (!integer_zerop (TREE_OPERAND (base, 1)))
1225 if (!tree_fits_shwi_p (TREE_OPERAND (base, 1)))
1227 if (dump_file)
1229 fprintf (dump_file, " base mem ref:");
1230 print_generic_expr (dump_file, base, TDF_SLIM);
1231 fprintf (dump_file, " has non-representable offset:");
1232 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1233 fprintf (dump_file, "\n");
1235 return NULL_TREE;
1237 else
1238 offset += tree_to_shwi (TREE_OPERAND (base, 1)) * BITS_PER_UNIT;
1241 else if (!operand_equal_p (tci->instance, base, 0)
1242 || tci->offset)
1244 if (dump_file)
1246 fprintf (dump_file, " base:");
1247 print_generic_expr (dump_file, base, TDF_SLIM);
1248 fprintf (dump_file, " does not match instance:");
1249 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1250 fprintf (dump_file, " with offset %i\n", (int)tci->offset);
1252 return tci->offset > POINTER_SIZE ? error_mark_node : NULL_TREE;
1254 if (offset != tci->offset
1255 || size != POINTER_SIZE
1256 || max_size != POINTER_SIZE)
1258 if (dump_file)
1259 fprintf (dump_file, " wrong offset %i!=%i or size %i\n",
1260 (int)offset, (int)tci->offset, (int)size);
1261 return offset + POINTER_SIZE <= tci->offset
1262 || (max_size != -1
1263 && tci->offset + POINTER_SIZE > offset + max_size)
1264 ? error_mark_node : NULL;
1268 tree vtable;
1269 unsigned HOST_WIDE_INT offset2;
1271 if (!vtable_pointer_value_to_vtable (rhs, &vtable, &offset2))
1273 if (dump_file)
1274 fprintf (dump_file, " Failed to lookup binfo\n");
1275 return NULL;
1278 tree binfo = subbinfo_with_vtable_at_offset (TYPE_BINFO (DECL_CONTEXT (vtable)),
1279 offset2, vtable);
1280 if (!binfo)
1282 if (dump_file)
1283 fprintf (dump_file, " Construction vtable used\n");
1284 /* FIXME: We should suport construction contexts. */
1285 return NULL;
1288 *type_offset = tree_to_shwi (BINFO_OFFSET (binfo)) * BITS_PER_UNIT;
1289 return DECL_CONTEXT (vtable);
1292 /* Record dynamic type change of TCI to TYPE. */
1294 static void
1295 record_known_type (struct type_change_info *tci, tree type, HOST_WIDE_INT offset)
1297 if (dump_file)
1299 if (type)
1301 fprintf (dump_file, " Recording type: ");
1302 print_generic_expr (dump_file, type, TDF_SLIM);
1303 fprintf (dump_file, " at offset %i\n", (int)offset);
1305 else
1306 fprintf (dump_file, " Recording unknown type\n");
1309 /* If we found a constructor of type that is not polymorphic or
1310 that may contain the type in question as a field (not as base),
1311 restrict to the inner class first to make type matching bellow
1312 happier. */
1313 if (type
1314 && (offset
1315 || (TREE_CODE (type) != RECORD_TYPE
1316 || !TYPE_BINFO (type)
1317 || !polymorphic_type_binfo_p (TYPE_BINFO (type)))))
1319 ipa_polymorphic_call_context context;
1321 context.offset = offset;
1322 context.outer_type = type;
1323 context.maybe_in_construction = false;
1324 context.maybe_derived_type = false;
1325 context.dynamic = true;
1326 /* If we failed to find the inner type, we know that the call
1327 would be undefined for type produced here. */
1328 if (!context.restrict_to_inner_class (tci->otr_type))
1330 if (dump_file)
1331 fprintf (dump_file, " Ignoring; does not contain otr_type\n");
1332 return;
1334 /* Watch for case we reached an POD type and anticipate placement
1335 new. */
1336 if (!context.maybe_derived_type)
1338 type = context.outer_type;
1339 offset = context.offset;
1342 if (tci->type_maybe_changed
1343 && (!types_same_for_odr (type, tci->known_current_type)
1344 || offset != tci->known_current_offset))
1345 tci->multiple_types_encountered = true;
1346 tci->known_current_type = TYPE_MAIN_VARIANT (type);
1347 tci->known_current_offset = offset;
1348 tci->type_maybe_changed = true;
1351 /* Callback of walk_aliased_vdefs and a helper function for
1352 detect_type_change to check whether a particular statement may modify
1353 the virtual table pointer, and if possible also determine the new type of
1354 the (sub-)object. It stores its result into DATA, which points to a
1355 type_change_info structure. */
1357 static bool
1358 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
1360 gimple stmt = SSA_NAME_DEF_STMT (vdef);
1361 struct type_change_info *tci = (struct type_change_info *) data;
1362 tree fn;
1364 /* If we already gave up, just terminate the rest of walk. */
1365 if (tci->multiple_types_encountered)
1366 return true;
1368 if (is_gimple_call (stmt))
1370 if (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))
1371 return false;
1373 /* Check for a constructor call. */
1374 if ((fn = gimple_call_fndecl (stmt)) != NULL_TREE
1375 && DECL_CXX_CONSTRUCTOR_P (fn)
1376 && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
1377 && gimple_call_num_args (stmt))
1379 tree op = walk_ssa_copies (gimple_call_arg (stmt, 0));
1380 tree type = method_class_type (TREE_TYPE (fn));
1381 HOST_WIDE_INT offset = 0, size, max_size;
1383 if (dump_file)
1385 fprintf (dump_file, " Checking constructor call: ");
1386 print_gimple_stmt (dump_file, stmt, 0, 0);
1389 /* See if THIS parameter seems like instance pointer. */
1390 if (TREE_CODE (op) == ADDR_EXPR)
1392 op = get_ref_base_and_extent (TREE_OPERAND (op, 0),
1393 &offset, &size, &max_size);
1394 if (size != max_size || max_size == -1)
1396 tci->speculative = true;
1397 return false;
1399 if (op && TREE_CODE (op) == MEM_REF)
1401 if (!tree_fits_shwi_p (TREE_OPERAND (op, 1)))
1403 tci->speculative = true;
1404 return false;
1406 offset += tree_to_shwi (TREE_OPERAND (op, 1))
1407 * BITS_PER_UNIT;
1408 op = TREE_OPERAND (op, 0);
1410 else if (DECL_P (op))
1412 else
1414 tci->speculative = true;
1415 return false;
1417 op = walk_ssa_copies (op);
1419 if (operand_equal_p (op, tci->instance, 0)
1420 && TYPE_SIZE (type)
1421 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
1422 && tree_fits_shwi_p (TYPE_SIZE (type))
1423 && tree_to_shwi (TYPE_SIZE (type)) + offset > tci->offset)
1425 record_known_type (tci, type, tci->offset - offset);
1426 return true;
1429 /* Calls may possibly change dynamic type by placement new. Assume
1430 it will not happen, but make result speculative only. */
1431 if (dump_file)
1433 fprintf (dump_file, " Function call may change dynamic type:");
1434 print_gimple_stmt (dump_file, stmt, 0, 0);
1436 tci->speculative = true;
1437 return false;
1439 /* Check for inlined virtual table store. */
1440 else if (noncall_stmt_may_be_vtbl_ptr_store (stmt))
1442 tree type;
1443 HOST_WIDE_INT offset = 0;
1444 if (dump_file)
1446 fprintf (dump_file, " Checking vtbl store: ");
1447 print_gimple_stmt (dump_file, stmt, 0, 0);
1450 type = extr_type_from_vtbl_ptr_store (stmt, tci, &offset);
1451 if (type == error_mark_node)
1452 return false;
1453 gcc_assert (!type || TYPE_MAIN_VARIANT (type) == type);
1454 if (!type)
1456 if (dump_file)
1457 fprintf (dump_file, " Unanalyzed store may change type.\n");
1458 tci->seen_unanalyzed_store = true;
1459 tci->speculative = true;
1461 else
1462 record_known_type (tci, type, offset);
1463 return true;
1465 else
1466 return false;
1469 /* THIS is polymorphic call context obtained from get_polymorphic_context.
1470 OTR_OBJECT is pointer to the instance returned by OBJ_TYPE_REF_OBJECT.
1471 INSTANCE is pointer to the outer instance as returned by
1472 get_polymorphic_context. To avoid creation of temporary expressions,
1473 INSTANCE may also be an declaration of get_polymorphic_context found the
1474 value to be in static storage.
1476 If the type of instance is not fully determined
1477 (either OUTER_TYPE is unknown or MAYBE_IN_CONSTRUCTION/INCLUDE_DERIVED_TYPES
1478 is set), try to walk memory writes and find the actual construction of the
1479 instance.
1481 Return true if memory is unchanged from function entry.
1483 We do not include this analysis in the context analysis itself, because
1484 it needs memory SSA to be fully built and the walk may be expensive.
1485 So it is not suitable for use withing fold_stmt and similar uses. */
1487 bool
1488 ipa_polymorphic_call_context::get_dynamic_type (tree instance,
1489 tree otr_object,
1490 tree otr_type,
1491 gimple call)
1493 struct type_change_info tci;
1494 ao_ref ao;
1495 bool function_entry_reached = false;
1496 tree instance_ref = NULL;
1497 gimple stmt = call;
1498 /* Remember OFFSET before it is modified by restrict_to_inner_class.
1499 This is because we do not update INSTANCE when walking inwards. */
1500 HOST_WIDE_INT instance_offset = offset;
1502 if (otr_type)
1503 otr_type = TYPE_MAIN_VARIANT (otr_type);
1505 /* Walk into inner type. This may clear maybe_derived_type and save us
1506 from useless work. It also makes later comparsions with static type
1507 easier. */
1508 if (outer_type && otr_type)
1510 if (!restrict_to_inner_class (otr_type))
1511 return false;
1514 if (!maybe_in_construction && !maybe_derived_type)
1515 return false;
1517 /* We need to obtain refernce to virtual table pointer. It is better
1518 to look it up in the code rather than build our own. This require bit
1519 of pattern matching, but we end up verifying that what we found is
1520 correct.
1522 What we pattern match is:
1524 tmp = instance->_vptr.A; // vtbl ptr load
1525 tmp2 = tmp[otr_token]; // vtable lookup
1526 OBJ_TYPE_REF(tmp2;instance->0) (instance);
1528 We want to start alias oracle walk from vtbl pointer load,
1529 but we may not be able to identify it, for example, when PRE moved the
1530 load around. */
1532 if (gimple_code (call) == GIMPLE_CALL)
1534 tree ref = gimple_call_fn (call);
1535 HOST_WIDE_INT offset2, size, max_size;
1537 if (TREE_CODE (ref) == OBJ_TYPE_REF)
1539 ref = OBJ_TYPE_REF_EXPR (ref);
1540 ref = walk_ssa_copies (ref);
1542 /* Check if definition looks like vtable lookup. */
1543 if (TREE_CODE (ref) == SSA_NAME
1544 && !SSA_NAME_IS_DEFAULT_DEF (ref)
1545 && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref))
1546 && TREE_CODE (gimple_assign_rhs1
1547 (SSA_NAME_DEF_STMT (ref))) == MEM_REF)
1549 ref = get_base_address
1550 (TREE_OPERAND (gimple_assign_rhs1
1551 (SSA_NAME_DEF_STMT (ref)), 0));
1552 ref = walk_ssa_copies (ref);
1553 /* Find base address of the lookup and see if it looks like
1554 vptr load. */
1555 if (TREE_CODE (ref) == SSA_NAME
1556 && !SSA_NAME_IS_DEFAULT_DEF (ref)
1557 && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref)))
1559 tree ref_exp = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (ref));
1560 tree base_ref = get_ref_base_and_extent
1561 (ref_exp, &offset2, &size, &max_size);
1563 /* Finally verify that what we found looks like read from OTR_OBJECT
1564 or from INSTANCE with offset OFFSET. */
1565 if (base_ref
1566 && ((TREE_CODE (base_ref) == MEM_REF
1567 && ((offset2 == instance_offset
1568 && TREE_OPERAND (base_ref, 0) == instance)
1569 || (!offset2 && TREE_OPERAND (base_ref, 0) == otr_object)))
1570 || (DECL_P (instance) && base_ref == instance
1571 && offset2 == instance_offset)))
1573 stmt = SSA_NAME_DEF_STMT (ref);
1574 instance_ref = ref_exp;
1581 /* If we failed to look up the refernece in code, build our own. */
1582 if (!instance_ref)
1584 /* If the statement in question does not use memory, we can't tell
1585 anything. */
1586 if (!gimple_vuse (stmt))
1587 return false;
1588 ao_ref_init_from_ptr_and_size (&ao, otr_object, NULL);
1590 else
1591 /* Otherwise use the real reference. */
1592 ao_ref_init (&ao, instance_ref);
1594 /* We look for vtbl pointer read. */
1595 ao.size = POINTER_SIZE;
1596 ao.max_size = ao.size;
1597 if (otr_type)
1598 ao.ref_alias_set
1599 = get_deref_alias_set (TREE_TYPE (BINFO_VTABLE (TYPE_BINFO (otr_type))));
1601 if (dump_file)
1603 fprintf (dump_file, "Determining dynamic type for call: ");
1604 print_gimple_stmt (dump_file, call, 0, 0);
1605 fprintf (dump_file, " Starting walk at: ");
1606 print_gimple_stmt (dump_file, stmt, 0, 0);
1607 fprintf (dump_file, " instance pointer: ");
1608 print_generic_expr (dump_file, otr_object, TDF_SLIM);
1609 fprintf (dump_file, " Outer instance pointer: ");
1610 print_generic_expr (dump_file, instance, TDF_SLIM);
1611 fprintf (dump_file, " offset: %i (bits)", (int)offset);
1612 fprintf (dump_file, " vtbl reference: ");
1613 print_generic_expr (dump_file, instance_ref, TDF_SLIM);
1614 fprintf (dump_file, "\n");
1617 tci.offset = offset;
1618 tci.instance = instance;
1619 tci.vtbl_ptr_ref = instance_ref;
1620 gcc_assert (TREE_CODE (instance) != MEM_REF);
1621 tci.known_current_type = NULL_TREE;
1622 tci.known_current_offset = 0;
1623 tci.otr_type = otr_type;
1624 tci.type_maybe_changed = false;
1625 tci.multiple_types_encountered = false;
1626 tci.speculative = false;
1627 tci.seen_unanalyzed_store = false;
1629 walk_aliased_vdefs (&ao, gimple_vuse (stmt), check_stmt_for_type_change,
1630 &tci, NULL, &function_entry_reached);
1632 /* If we did not find any type changing statements, we may still drop
1633 maybe_in_construction flag if the context already have outer type.
1635 Here we make special assumptions about both constructors and
1636 destructors which are all the functions that are allowed to alter the
1637 VMT pointers. It assumes that destructors begin with assignment into
1638 all VMT pointers and that constructors essentially look in the
1639 following way:
1641 1) The very first thing they do is that they call constructors of
1642 ancestor sub-objects that have them.
1644 2) Then VMT pointers of this and all its ancestors is set to new
1645 values corresponding to the type corresponding to the constructor.
1647 3) Only afterwards, other stuff such as constructor of member
1648 sub-objects and the code written by the user is run. Only this may
1649 include calling virtual functions, directly or indirectly.
1651 4) placement new can not be used to change type of non-POD statically
1652 allocated variables.
1654 There is no way to call a constructor of an ancestor sub-object in any
1655 other way.
1657 This means that we do not have to care whether constructors get the
1658 correct type information because they will always change it (in fact,
1659 if we define the type to be given by the VMT pointer, it is undefined).
1661 The most important fact to derive from the above is that if, for some
1662 statement in the section 3, we try to detect whether the dynamic type
1663 has changed, we can safely ignore all calls as we examine the function
1664 body backwards until we reach statements in section 2 because these
1665 calls cannot be ancestor constructors or destructors (if the input is
1666 not bogus) and so do not change the dynamic type (this holds true only
1667 for automatically allocated objects but at the moment we devirtualize
1668 only these). We then must detect that statements in section 2 change
1669 the dynamic type and can try to derive the new type. That is enough
1670 and we can stop, we will never see the calls into constructors of
1671 sub-objects in this code.
1673 Therefore if the static outer type was found (outer_type)
1674 we can safely ignore tci.speculative that is set on calls and give up
1675 only if there was dyanmic type store that may affect given variable
1676 (seen_unanalyzed_store) */
1678 if (!tci.type_maybe_changed
1679 || (outer_type
1680 && !dynamic
1681 && !tci.seen_unanalyzed_store
1682 && !tci.multiple_types_encountered
1683 && offset == tci.offset
1684 && types_same_for_odr (tci.known_current_type,
1685 outer_type)))
1687 if (!outer_type || tci.seen_unanalyzed_store)
1688 return false;
1689 if (maybe_in_construction)
1690 maybe_in_construction = false;
1691 if (dump_file)
1692 fprintf (dump_file, " No dynamic type change found.\n");
1693 return true;
1696 if (tci.known_current_type
1697 && !function_entry_reached
1698 && !tci.multiple_types_encountered)
1700 if (!tci.speculative)
1702 outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
1703 offset = tci.known_current_offset;
1704 dynamic = true;
1705 maybe_in_construction = false;
1706 maybe_derived_type = false;
1707 if (dump_file)
1708 fprintf (dump_file, " Determined dynamic type.\n");
1710 else if (!speculative_outer_type
1711 || speculative_maybe_derived_type)
1713 speculative_outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
1714 speculative_offset = tci.known_current_offset;
1715 speculative_maybe_derived_type = false;
1716 if (dump_file)
1717 fprintf (dump_file, " Determined speculative dynamic type.\n");
1720 else if (dump_file)
1722 fprintf (dump_file, " Found multiple types%s%s\n",
1723 function_entry_reached ? " (function entry reached)" : "",
1724 function_entry_reached ? " (multiple types encountered)" : "");
1727 return false;
1730 /* See if speculation given by SPEC_OUTER_TYPE, SPEC_OFFSET and SPEC_MAYBE_DERIVED_TYPE
1731 seems consistent (and useful) with what we already have in the non-speculative context. */
1733 bool
1734 ipa_polymorphic_call_context::speculation_consistent_p (tree spec_outer_type,
1735 HOST_WIDE_INT spec_offset,
1736 bool spec_maybe_derived_type,
1737 tree otr_type) const
1739 if (!flag_devirtualize_speculatively)
1740 return false;
1742 /* Non-polymorphic types are useless for deriving likely polymorphic
1743 call targets. */
1744 if (!spec_outer_type || !contains_polymorphic_type_p (spec_outer_type))
1745 return false;
1747 /* If we know nothing, speculation is always good. */
1748 if (!outer_type)
1749 return true;
1751 /* Speculation is only useful to avoid derived types.
1752 This is not 100% true for placement new, where the outer context may
1753 turn out to be useless, but ignore these for now. */
1754 if (!maybe_derived_type)
1755 return false;
1757 /* If types agrees, speculation is consistent, but it makes sense only
1758 when it says something new. */
1759 if (types_must_be_same_for_odr (spec_outer_type, outer_type))
1760 return maybe_derived_type && !spec_maybe_derived_type;
1762 /* If speculation does not contain the type in question, ignore it. */
1763 if (otr_type
1764 && !contains_type_p (spec_outer_type, spec_offset, otr_type, false, true))
1765 return false;
1767 /* If outer type already contains speculation as a filed,
1768 it is useless. We already know from OUTER_TYPE
1769 SPEC_TYPE and that it is not in the construction. */
1770 if (contains_type_p (outer_type, offset - spec_offset,
1771 spec_outer_type, false, false))
1772 return false;
1774 /* If speculative outer type is not more specified than outer
1775 type, just give up.
1776 We can only decide this safely if we can compare types with OUTER_TYPE.
1778 if ((!in_lto_p || odr_type_p (outer_type))
1779 && !contains_type_p (spec_outer_type,
1780 spec_offset - offset,
1781 outer_type, false))
1782 return false;
1783 return true;
1786 /* Improve THIS with speculation described by NEW_OUTER_TYPE, NEW_OFFSET,
1787 NEW_MAYBE_DERIVED_TYPE
1788 If OTR_TYPE is set, assume the context is used with OTR_TYPE. */
1790 bool
1791 ipa_polymorphic_call_context::combine_speculation_with
1792 (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
1793 tree otr_type)
1795 if (!new_outer_type)
1796 return false;
1798 /* restrict_to_inner_class may eliminate wrong speculation making our job
1799 easeier. */
1800 if (otr_type)
1801 restrict_to_inner_class (otr_type);
1803 if (!speculation_consistent_p (new_outer_type, new_offset,
1804 new_maybe_derived_type, otr_type))
1805 return false;
1807 /* New speculation is a win in case we have no speculation or new
1808 speculation does not consider derivations. */
1809 if (!speculative_outer_type
1810 || (speculative_maybe_derived_type
1811 && !new_maybe_derived_type))
1813 speculative_outer_type = new_outer_type;
1814 speculative_offset = new_offset;
1815 speculative_maybe_derived_type = new_maybe_derived_type;
1816 return true;
1818 else if (types_must_be_same_for_odr (speculative_outer_type,
1819 new_outer_type))
1821 if (speculative_offset != new_offset)
1823 /* OK we have two contexts that seems valid but they disagree,
1824 just give up.
1826 This is not a lattice operation, so we may want to drop it later. */
1827 if (dump_file && (dump_flags & TDF_DETAILS))
1828 fprintf (dump_file,
1829 "Speculative outer types match, "
1830 "offset mismatch -> invalid speculation\n");
1831 clear_speculation ();
1832 return true;
1834 else
1836 if (speculative_maybe_derived_type && !new_maybe_derived_type)
1838 speculative_maybe_derived_type = false;
1839 return true;
1841 else
1842 return false;
1845 /* Choose type that contains the other. This one either contains the outer
1846 as a field (thus giving exactly one target) or is deeper in the type
1847 hiearchy. */
1848 else if (speculative_outer_type
1849 && speculative_maybe_derived_type
1850 && (new_offset > speculative_offset
1851 || (new_offset == speculative_offset
1852 && contains_type_p (new_outer_type,
1853 0, speculative_outer_type, false))))
1855 tree old_outer_type = speculative_outer_type;
1856 HOST_WIDE_INT old_offset = speculative_offset;
1857 bool old_maybe_derived_type = speculative_maybe_derived_type;
1859 speculative_outer_type = new_outer_type;
1860 speculative_offset = new_offset;
1861 speculative_maybe_derived_type = new_maybe_derived_type;
1863 if (otr_type)
1864 restrict_to_inner_class (otr_type);
1866 /* If the speculation turned out to make no sense, revert to sensible
1867 one. */
1868 if (!speculative_outer_type)
1870 speculative_outer_type = old_outer_type;
1871 speculative_offset = old_offset;
1872 speculative_maybe_derived_type = old_maybe_derived_type;
1873 return false;
1875 return (old_offset != speculative_offset
1876 || old_maybe_derived_type != speculative_maybe_derived_type
1877 || types_must_be_same_for_odr (speculative_outer_type,
1878 new_outer_type));
1880 return false;
1883 /* Make speculation less specific so
1884 NEW_OUTER_TYPE, NEW_OFFSET, NEW_MAYBE_DERIVED_TYPE is also included.
1885 If OTR_TYPE is set, assume the context is used with OTR_TYPE. */
1887 bool
1888 ipa_polymorphic_call_context::meet_speculation_with
1889 (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
1890 tree otr_type)
1892 if (!new_outer_type && speculative_outer_type)
1894 clear_speculation ();
1895 return true;
1898 /* restrict_to_inner_class may eliminate wrong speculation making our job
1899 easeier. */
1900 if (otr_type)
1901 restrict_to_inner_class (otr_type);
1903 if (!speculative_outer_type
1904 || !speculation_consistent_p (speculative_outer_type,
1905 speculative_offset,
1906 speculative_maybe_derived_type,
1907 otr_type))
1908 return false;
1910 if (!speculation_consistent_p (new_outer_type, new_offset,
1911 new_maybe_derived_type, otr_type))
1913 clear_speculation ();
1914 return true;
1917 else if (types_must_be_same_for_odr (speculative_outer_type,
1918 new_outer_type))
1920 if (speculative_offset != new_offset)
1922 clear_speculation ();
1923 return true;
1925 else
1927 if (!speculative_maybe_derived_type && new_maybe_derived_type)
1929 speculative_maybe_derived_type = true;
1930 return true;
1932 else
1933 return false;
1936 /* See if one type contains the other as a field (not base). */
1937 else if (contains_type_p (new_outer_type, new_offset - speculative_offset,
1938 speculative_outer_type, false, false))
1939 return false;
1940 else if (contains_type_p (speculative_outer_type,
1941 speculative_offset - new_offset,
1942 new_outer_type, false, false))
1944 speculative_outer_type = new_outer_type;
1945 speculative_offset = new_offset;
1946 speculative_maybe_derived_type = new_maybe_derived_type;
1947 return true;
1949 /* See if OUTER_TYPE is base of CTX.OUTER_TYPE. */
1950 else if (contains_type_p (new_outer_type,
1951 new_offset - speculative_offset,
1952 speculative_outer_type, false, true))
1954 if (!speculative_maybe_derived_type)
1956 speculative_maybe_derived_type = true;
1957 return true;
1959 return false;
1961 /* See if CTX.OUTER_TYPE is base of OUTER_TYPE. */
1962 else if (contains_type_p (speculative_outer_type,
1963 speculative_offset - new_offset, new_outer_type, false, true))
1965 speculative_outer_type = new_outer_type;
1966 speculative_offset = new_offset;
1967 speculative_maybe_derived_type = true;
1968 return true;
1970 else
1972 if (dump_file && (dump_flags & TDF_DETAILS))
1973 fprintf (dump_file, "Giving up on speculative meet\n");
1974 clear_speculation ();
1975 return true;
1979 /* Assume that both THIS and a given context is valid and strenghten THIS
1980 if possible. Return true if any strenghtening was made.
1981 If actual type the context is being used in is known, OTR_TYPE should be
1982 set accordingly. This improves quality of combined result. */
1984 bool
1985 ipa_polymorphic_call_context::combine_with (ipa_polymorphic_call_context ctx,
1986 tree otr_type)
1988 bool updated = false;
1990 if (ctx.useless_p () || invalid)
1991 return false;
1993 /* Restricting context to inner type makes merging easier, however do not
1994 do that unless we know how the context is used (OTR_TYPE is non-NULL) */
1995 if (otr_type && !invalid && !ctx.invalid)
1997 restrict_to_inner_class (otr_type);
1998 ctx.restrict_to_inner_class (otr_type);
1999 if(invalid)
2000 return false;
2003 if (dump_file && (dump_flags & TDF_DETAILS))
2005 fprintf (dump_file, "Polymorphic call context combine:");
2006 dump (dump_file);
2007 fprintf (dump_file, "With context: ");
2008 ctx.dump (dump_file);
2009 if (otr_type)
2011 fprintf (dump_file, "To be used with type: ");
2012 print_generic_expr (dump_file, otr_type, TDF_SLIM);
2013 fprintf (dump_file, "\n");
2017 /* If call is known to be invalid, we are done. */
2018 if (ctx.invalid)
2020 if (dump_file && (dump_flags & TDF_DETAILS))
2021 fprintf (dump_file, "-> Invalid context\n");
2022 goto invalidate;
2025 if (!ctx.outer_type)
2027 else if (!outer_type)
2029 outer_type = ctx.outer_type;
2030 offset = ctx.offset;
2031 dynamic = ctx.dynamic;
2032 maybe_in_construction = ctx.maybe_in_construction;
2033 maybe_derived_type = ctx.maybe_derived_type;
2034 updated = true;
2036 /* If types are known to be same, merging is quite easy. */
2037 else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
2039 if (offset != ctx.offset
2040 && TYPE_SIZE (outer_type)
2041 && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
2043 if (dump_file && (dump_flags & TDF_DETAILS))
2044 fprintf (dump_file, "Outer types match, offset mismatch -> invalid\n");
2045 clear_speculation ();
2046 clear_outer_type ();
2047 invalid = true;
2048 return true;
2050 if (dump_file && (dump_flags & TDF_DETAILS))
2051 fprintf (dump_file, "Outer types match, merging flags\n");
2052 if (maybe_in_construction && !ctx.maybe_in_construction)
2054 updated = true;
2055 maybe_in_construction = false;
2057 if (maybe_derived_type && !ctx.maybe_derived_type)
2059 updated = true;
2060 maybe_derived_type = false;
2062 if (dynamic && !ctx.dynamic)
2064 updated = true;
2065 dynamic = false;
2068 /* If we know the type precisely, there is not much to improve. */
2069 else if (!maybe_derived_type && !maybe_in_construction
2070 && !ctx.maybe_derived_type && !ctx.maybe_in_construction)
2072 /* It may be easy to check if second context permits the first
2073 and set INVALID otherwise. This is not easy to do in general;
2074 contains_type_p may return false negatives for non-comparable
2075 types.
2077 If OTR_TYPE is known, we however can expect that
2078 restrict_to_inner_class should have discovered the same base
2079 type. */
2080 if (otr_type && !ctx.maybe_in_construction && !ctx.maybe_derived_type)
2082 if (dump_file && (dump_flags & TDF_DETAILS))
2083 fprintf (dump_file, "Contextes disagree -> invalid\n");
2084 goto invalidate;
2087 /* See if one type contains the other as a field (not base).
2088 In this case we want to choose the wider type, because it contains
2089 more information. */
2090 else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
2091 outer_type, false, false))
2093 if (dump_file && (dump_flags & TDF_DETAILS))
2094 fprintf (dump_file, "Second type contain the first as a field\n");
2096 if (maybe_derived_type)
2098 outer_type = ctx.outer_type;
2099 maybe_derived_type = ctx.maybe_derived_type;
2100 offset = ctx.offset;
2101 dynamic = ctx.dynamic;
2102 updated = true;
2105 /* If we do not know how the context is being used, we can
2106 not clear MAYBE_IN_CONSTRUCTION because it may be offseted
2107 to other component of OUTER_TYPE later and we know nothing
2108 about it. */
2109 if (otr_type && maybe_in_construction
2110 && !ctx.maybe_in_construction)
2112 maybe_in_construction = false;
2113 updated = true;
2116 else if (contains_type_p (outer_type, offset - ctx.offset,
2117 ctx.outer_type, false, false))
2119 if (dump_file && (dump_flags & TDF_DETAILS))
2120 fprintf (dump_file, "First type contain the second as a field\n");
2122 if (otr_type && maybe_in_construction
2123 && !ctx.maybe_in_construction)
2125 maybe_in_construction = false;
2126 updated = true;
2129 /* See if OUTER_TYPE is base of CTX.OUTER_TYPE. */
2130 else if (contains_type_p (ctx.outer_type,
2131 ctx.offset - offset, outer_type, false, true))
2133 if (dump_file && (dump_flags & TDF_DETAILS))
2134 fprintf (dump_file, "First type is base of second\n");
2135 if (!maybe_derived_type)
2137 if (!ctx.maybe_in_construction
2138 && types_odr_comparable (outer_type, ctx.outer_type))
2140 if (dump_file && (dump_flags & TDF_DETAILS))
2141 fprintf (dump_file, "Second context does not permit base -> invalid\n");
2142 goto invalidate;
2145 /* Pick variant deeper in the hiearchy. */
2146 else
2148 outer_type = ctx.outer_type;
2149 maybe_in_construction = ctx.maybe_in_construction;
2150 maybe_derived_type = ctx.maybe_derived_type;
2151 offset = ctx.offset;
2152 dynamic = ctx.dynamic;
2153 updated = true;
2156 /* See if CTX.OUTER_TYPE is base of OUTER_TYPE. */
2157 else if (contains_type_p (outer_type,
2158 offset - ctx.offset, ctx.outer_type, false, true))
2160 if (dump_file && (dump_flags & TDF_DETAILS))
2161 fprintf (dump_file, "Second type is base of first\n");
2162 if (!ctx.maybe_derived_type)
2164 if (!maybe_in_construction
2165 && types_odr_comparable (outer_type, ctx.outer_type))
2167 if (dump_file && (dump_flags & TDF_DETAILS))
2168 fprintf (dump_file, "First context does not permit base -> invalid\n");
2169 goto invalidate;
2171 /* Pick the base type. */
2172 else if (maybe_in_construction)
2174 outer_type = ctx.outer_type;
2175 maybe_in_construction = ctx.maybe_in_construction;
2176 maybe_derived_type = ctx.maybe_derived_type;
2177 offset = ctx.offset;
2178 dynamic = ctx.dynamic;
2179 updated = true;
2183 /* TODO handle merging using hiearchy. */
2184 else if (dump_file && (dump_flags & TDF_DETAILS))
2185 fprintf (dump_file, "Giving up on merge\n");
2187 updated |= combine_speculation_with (ctx.speculative_outer_type,
2188 ctx.speculative_offset,
2189 ctx.speculative_maybe_derived_type,
2190 otr_type);
2192 if (updated && dump_file && (dump_flags & TDF_DETAILS))
2194 fprintf (dump_file, "Updated as: ");
2195 dump (dump_file);
2196 fprintf (dump_file, "\n");
2198 return updated;
2200 invalidate:
2201 invalid = true;
2202 clear_speculation ();
2203 clear_outer_type ();
2204 return true;
2207 /* Take non-speculative info, merge it with speculative and clear speculation.
2208 Used when we no longer manage to keep track of actual outer type, but we
2209 think it is still there.
2211 If OTR_TYPE is set, the transformation can be done more effectively assuming
2212 that context is going to be used only that way. */
2214 void
2215 ipa_polymorphic_call_context::make_speculative (tree otr_type)
2217 tree spec_outer_type = outer_type;
2218 HOST_WIDE_INT spec_offset = offset;
2219 bool spec_maybe_derived_type = maybe_derived_type;
2221 if (invalid)
2223 invalid = false;
2224 clear_outer_type ();
2225 clear_speculation ();
2226 return;
2228 if (!outer_type)
2229 return;
2230 clear_outer_type ();
2231 combine_speculation_with (spec_outer_type, spec_offset,
2232 spec_maybe_derived_type,
2233 otr_type);
2236 /* Use when we can not track dynamic type change. This speculatively assume
2237 type change is not happening. */
2239 void
2240 ipa_polymorphic_call_context::possible_dynamic_type_change (bool in_poly_cdtor,
2241 tree otr_type)
2243 if (dynamic)
2244 make_speculative (otr_type);
2245 else if (in_poly_cdtor)
2246 maybe_in_construction = true;
2249 /* Return TRUE if this context conveys the same information as OTHER. */
2251 bool
2252 ipa_polymorphic_call_context::equal_to
2253 (const ipa_polymorphic_call_context &x) const
2255 if (useless_p ())
2256 return x.useless_p ();
2257 if (invalid)
2258 return x.invalid;
2259 if (x.useless_p () || x.invalid)
2260 return false;
2262 if (outer_type)
2264 if (!x.outer_type
2265 || !types_odr_comparable (outer_type, x.outer_type)
2266 || !types_same_for_odr (outer_type, x.outer_type)
2267 || offset != x.offset
2268 || maybe_in_construction != x.maybe_in_construction
2269 || maybe_derived_type != x.maybe_derived_type
2270 || dynamic != x.dynamic)
2271 return false;
2273 else if (x.outer_type)
2274 return false;
2277 if (speculative_outer_type
2278 && speculation_consistent_p (speculative_outer_type, speculative_offset,
2279 speculative_maybe_derived_type, NULL_TREE))
2281 if (!x.speculative_outer_type)
2282 return false;
2284 if (!types_odr_comparable (speculative_outer_type,
2285 x.speculative_outer_type)
2286 || !types_same_for_odr (speculative_outer_type,
2287 x.speculative_outer_type)
2288 || speculative_offset != x.speculative_offset
2289 || speculative_maybe_derived_type != x.speculative_maybe_derived_type)
2290 return false;
2292 else if (x.speculative_outer_type
2293 && x.speculation_consistent_p (x.speculative_outer_type,
2294 x.speculative_offset,
2295 x.speculative_maybe_derived_type,
2296 NULL))
2297 return false;
2299 return true;
2302 /* Modify context to be strictly less restrictive than CTX. */
2304 bool
2305 ipa_polymorphic_call_context::meet_with (ipa_polymorphic_call_context ctx,
2306 tree otr_type)
2308 bool updated = false;
2310 if (useless_p () || ctx.invalid)
2311 return false;
2313 /* Restricting context to inner type makes merging easier, however do not
2314 do that unless we know how the context is used (OTR_TYPE is non-NULL) */
2315 if (otr_type && !useless_p () && !ctx.useless_p ())
2317 restrict_to_inner_class (otr_type);
2318 ctx.restrict_to_inner_class (otr_type);
2319 if(invalid)
2320 return false;
2323 if (equal_to (ctx))
2324 return false;
2326 if (ctx.useless_p () || invalid)
2328 *this = ctx;
2329 return true;
2332 if (dump_file && (dump_flags & TDF_DETAILS))
2334 fprintf (dump_file, "Polymorphic call context meet:");
2335 dump (dump_file);
2336 fprintf (dump_file, "With context: ");
2337 ctx.dump (dump_file);
2338 if (otr_type)
2340 fprintf (dump_file, "To be used with type: ");
2341 print_generic_expr (dump_file, otr_type, TDF_SLIM);
2342 fprintf (dump_file, "\n");
2346 if (!dynamic && ctx.dynamic)
2348 dynamic = true;
2349 updated = true;
2352 /* If call is known to be invalid, we are done. */
2353 if (!outer_type)
2355 else if (!ctx.outer_type)
2357 clear_outer_type ();
2358 updated = true;
2360 /* If types are known to be same, merging is quite easy. */
2361 else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
2363 if (offset != ctx.offset
2364 && TYPE_SIZE (outer_type)
2365 && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
2367 if (dump_file && (dump_flags & TDF_DETAILS))
2368 fprintf (dump_file, "Outer types match, offset mismatch -> clearing\n");
2369 clear_outer_type ();
2370 return true;
2372 if (dump_file && (dump_flags & TDF_DETAILS))
2373 fprintf (dump_file, "Outer types match, merging flags\n");
2374 if (!maybe_in_construction && ctx.maybe_in_construction)
2376 updated = true;
2377 maybe_in_construction = true;
2379 if (!maybe_derived_type && ctx.maybe_derived_type)
2381 updated = true;
2382 maybe_derived_type = true;
2384 if (!dynamic && ctx.dynamic)
2386 updated = true;
2387 dynamic = true;
2390 /* See if one type contains the other as a field (not base). */
2391 else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
2392 outer_type, false, false))
2394 if (dump_file && (dump_flags & TDF_DETAILS))
2395 fprintf (dump_file, "Second type contain the first as a field\n");
2397 /* The second type is more specified, so we keep the first.
2398 We need to set DYNAMIC flag to avoid declaring context INVALID
2399 of OFFSET ends up being out of range. */
2400 if (!dynamic
2401 && (ctx.dynamic
2402 || (!otr_type
2403 && (!TYPE_SIZE (ctx.outer_type)
2404 || !TYPE_SIZE (outer_type)
2405 || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
2406 TYPE_SIZE (outer_type), 0)))))
2408 dynamic = true;
2409 updated = true;
2412 else if (contains_type_p (outer_type, offset - ctx.offset,
2413 ctx.outer_type, false, false))
2415 if (dump_file && (dump_flags & TDF_DETAILS))
2416 fprintf (dump_file, "First type contain the second as a field\n");
2418 if (!dynamic
2419 && (ctx.dynamic
2420 || (!otr_type
2421 && (!TYPE_SIZE (ctx.outer_type)
2422 || !TYPE_SIZE (outer_type)
2423 || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
2424 TYPE_SIZE (outer_type), 0)))))
2425 dynamic = true;
2426 outer_type = ctx.outer_type;
2427 offset = ctx.offset;
2428 dynamic = ctx.dynamic;
2429 maybe_in_construction = ctx.maybe_in_construction;
2430 maybe_derived_type = ctx.maybe_derived_type;
2431 updated = true;
2433 /* See if OUTER_TYPE is base of CTX.OUTER_TYPE. */
2434 else if (contains_type_p (ctx.outer_type,
2435 ctx.offset - offset, outer_type, false, true))
2437 if (dump_file && (dump_flags & TDF_DETAILS))
2438 fprintf (dump_file, "First type is base of second\n");
2439 if (!maybe_derived_type)
2441 maybe_derived_type = true;
2442 updated = true;
2444 if (!maybe_in_construction && ctx.maybe_in_construction)
2446 maybe_in_construction = true;
2447 updated = true;
2449 if (!dynamic && ctx.dynamic)
2451 dynamic = true;
2452 updated = true;
2455 /* See if CTX.OUTER_TYPE is base of OUTER_TYPE. */
2456 else if (contains_type_p (outer_type,
2457 offset - ctx.offset, ctx.outer_type, false, true))
2459 if (dump_file && (dump_flags & TDF_DETAILS))
2460 fprintf (dump_file, "Second type is base of first\n");
2461 outer_type = ctx.outer_type;
2462 offset = ctx.offset;
2463 updated = true;
2464 if (!maybe_derived_type)
2465 maybe_derived_type = true;
2466 if (!maybe_in_construction && ctx.maybe_in_construction)
2467 maybe_in_construction = true;
2468 if (!dynamic && ctx.dynamic)
2469 dynamic = true;
2471 /* TODO handle merging using hiearchy. */
2472 else
2474 if (dump_file && (dump_flags & TDF_DETAILS))
2475 fprintf (dump_file, "Giving up on meet\n");
2476 clear_outer_type ();
2477 updated = true;
2480 updated |= meet_speculation_with (ctx.speculative_outer_type,
2481 ctx.speculative_offset,
2482 ctx.speculative_maybe_derived_type,
2483 otr_type);
2485 if (updated && dump_file && (dump_flags & TDF_DETAILS))
2487 fprintf (dump_file, "Updated as: ");
2488 dump (dump_file);
2489 fprintf (dump_file, "\n");
2491 return updated;