Daily bump.
[official-gcc.git] / gcc / ipa-polymorphic-call.c
blobd876b3b1ab543c24b084927b8421e2ee76614d5c
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 "alias.h"
26 #include "symtab.h"
27 #include "tree.h"
28 #include "fold-const.h"
29 #include "print-tree.h"
30 #include "calls.h"
31 #include "hard-reg-set.h"
32 #include "function.h"
33 #include "rtl.h"
34 #include "flags.h"
35 #include "insn-config.h"
36 #include "expmed.h"
37 #include "dojump.h"
38 #include "explow.h"
39 #include "emit-rtl.h"
40 #include "varasm.h"
41 #include "stmt.h"
42 #include "expr.h"
43 #include "tree-pass.h"
44 #include "target.h"
45 #include "tree-pretty-print.h"
46 #include "predict.h"
47 #include "basic-block.h"
48 #include "cgraph.h"
49 #include "ipa-utils.h"
50 #include "tree-ssa-alias.h"
51 #include "internal-fn.h"
52 #include "gimple-fold.h"
53 #include "gimple-expr.h"
54 #include "gimple.h"
55 #include "alloc-pool.h"
56 #include "symbol-summary.h"
57 #include "ipa-prop.h"
58 #include "ipa-inline.h"
59 #include "diagnostic.h"
60 #include "tree-dfa.h"
61 #include "demangle.h"
62 #include "dbgcnt.h"
63 #include "gimple-pretty-print.h"
64 #include "stor-layout.h"
65 #include "intl.h"
66 #include "data-streamer.h"
67 #include "lto-streamer.h"
68 #include "streamer-hooks.h"
69 #include "tree-ssa-operands.h"
70 #include "tree-into-ssa.h"
72 /* Return true when TYPE contains an polymorphic type and thus is interesting
73 for devirtualization machinery. */
75 static bool contains_type_p (tree, HOST_WIDE_INT, tree,
76 bool consider_placement_new = true,
77 bool consider_bases = true);
79 bool
80 contains_polymorphic_type_p (const_tree type)
82 type = TYPE_MAIN_VARIANT (type);
84 if (RECORD_OR_UNION_TYPE_P (type))
86 if (TYPE_BINFO (type)
87 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
88 return true;
89 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
90 if (TREE_CODE (fld) == FIELD_DECL
91 && !DECL_ARTIFICIAL (fld)
92 && contains_polymorphic_type_p (TREE_TYPE (fld)))
93 return true;
94 return false;
96 if (TREE_CODE (type) == ARRAY_TYPE)
97 return contains_polymorphic_type_p (TREE_TYPE (type));
98 return false;
101 /* Return true if it seems valid to use placement new to build EXPECTED_TYPE
102 at possition CUR_OFFSET within TYPE.
104 POD can be changed to an instance of a polymorphic type by
105 placement new. Here we play safe and assume that any
106 non-polymorphic type is POD. */
107 bool
108 possible_placement_new (tree type, tree expected_type,
109 HOST_WIDE_INT cur_offset)
111 return ((TREE_CODE (type) != RECORD_TYPE
112 || !TYPE_BINFO (type)
113 || cur_offset >= POINTER_SIZE
114 || !polymorphic_type_binfo_p (TYPE_BINFO (type)))
115 && (!TYPE_SIZE (type)
116 || !tree_fits_shwi_p (TYPE_SIZE (type))
117 || (cur_offset
118 + (expected_type ? tree_to_uhwi (TYPE_SIZE (expected_type))
119 : POINTER_SIZE)
120 <= tree_to_uhwi (TYPE_SIZE (type)))));
123 /* THIS->OUTER_TYPE is a type of memory object where object of OTR_TYPE
124 is contained at THIS->OFFSET. Walk the memory representation of
125 THIS->OUTER_TYPE and find the outermost class type that match
126 OTR_TYPE or contain OTR_TYPE as a base. Update THIS
127 to represent it.
129 If OTR_TYPE is NULL, just find outermost polymorphic type with
130 virtual table present at possition OFFSET.
132 For example when THIS represents type
133 class A
135 int a;
136 class B b;
138 and we look for type at offset sizeof(int), we end up with B and offset 0.
139 If the same is produced by multiple inheritance, we end up with A and offset
140 sizeof(int).
142 If we can not find corresponding class, give up by setting
143 THIS->OUTER_TYPE to OTR_TYPE and THIS->OFFSET to NULL.
144 Return true when lookup was sucesful.
146 When CONSIDER_PLACEMENT_NEW is false, reject contexts that may be made
147 valid only via alocation of new polymorphic type inside by means
148 of placement new.
150 When CONSIDER_BASES is false, only look for actual fields, not base types
151 of TYPE. */
153 bool
154 ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type,
155 bool consider_placement_new,
156 bool consider_bases)
158 tree type = outer_type;
159 HOST_WIDE_INT cur_offset = offset;
160 bool speculative = false;
161 bool size_unknown = false;
162 unsigned HOST_WIDE_INT otr_type_size = POINTER_SIZE;
164 /* Update OUTER_TYPE to match EXPECTED_TYPE if it is not set. */
165 if (!outer_type)
167 clear_outer_type (otr_type);
168 type = otr_type;
169 cur_offset = 0;
171 /* See if OFFSET points inside OUTER_TYPE. If it does not, we know
172 that the context is either invalid, or the instance type must be
173 derived from OUTER_TYPE.
175 Because the instance type may contain field whose type is of OUTER_TYPE,
176 we can not derive any effective information about it.
178 TODO: In the case we know all derrived types, we can definitely do better
179 here. */
180 else if (TYPE_SIZE (outer_type)
181 && tree_fits_shwi_p (TYPE_SIZE (outer_type))
182 && tree_to_shwi (TYPE_SIZE (outer_type)) >= 0
183 && tree_to_shwi (TYPE_SIZE (outer_type)) <= offset)
185 clear_outer_type (otr_type);
186 type = otr_type;
187 cur_offset = 0;
189 /* If derived type is not allowed, we know that the context is invalid.
190 For dynamic types, we really do not have information about
191 size of the memory location. It is possible that completely
192 different type is stored after outer_type. */
193 if (!maybe_derived_type && !dynamic)
195 clear_speculation ();
196 invalid = true;
197 return false;
201 if (otr_type && TYPE_SIZE (otr_type)
202 && tree_fits_shwi_p (TYPE_SIZE (otr_type)))
203 otr_type_size = tree_to_uhwi (TYPE_SIZE (otr_type));
205 if (!type || offset < 0)
206 goto no_useful_type_info;
208 /* Find the sub-object the constant actually refers to and mark whether it is
209 an artificial one (as opposed to a user-defined one).
211 This loop is performed twice; first time for outer_type and second time
212 for speculative_outer_type. The second run has SPECULATIVE set. */
213 while (true)
215 unsigned HOST_WIDE_INT pos, size;
216 tree fld;
218 /* If we do not know size of TYPE, we need to be more conservative
219 about accepting cases where we can not find EXPECTED_TYPE.
220 Generally the types that do matter here are of constant size.
221 Size_unknown case should be very rare. */
222 if (TYPE_SIZE (type)
223 && tree_fits_shwi_p (TYPE_SIZE (type))
224 && tree_to_shwi (TYPE_SIZE (type)) >= 0)
225 size_unknown = false;
226 else
227 size_unknown = true;
229 /* On a match, just return what we found. */
230 if ((otr_type
231 && types_odr_comparable (type, otr_type)
232 && types_same_for_odr (type, otr_type))
233 || (!otr_type
234 && TREE_CODE (type) == RECORD_TYPE
235 && TYPE_BINFO (type)
236 && polymorphic_type_binfo_p (TYPE_BINFO (type))))
238 if (speculative)
240 /* If we did not match the offset, just give up on speculation. */
241 if (cur_offset != 0
242 /* Also check if speculation did not end up being same as
243 non-speculation. */
244 || (types_must_be_same_for_odr (speculative_outer_type,
245 outer_type)
246 && (maybe_derived_type
247 == speculative_maybe_derived_type)))
248 clear_speculation ();
249 return true;
251 else
253 /* If type is known to be final, do not worry about derived
254 types. Testing it here may help us to avoid speculation. */
255 if (otr_type && TREE_CODE (outer_type) == RECORD_TYPE
256 && (!in_lto_p || odr_type_p (outer_type))
257 && type_with_linkage_p (outer_type)
258 && type_known_to_have_no_derivations_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 = TYPE_MAIN_VARIANT (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 /* Return a FUNCTION_DECL if BLOCK represents a constructor or destructor.
503 If CHECK_CLONES is true, also check for clones of ctor/dtors. */
505 tree
506 inlined_polymorphic_ctor_dtor_block_p (tree block, bool check_clones)
508 tree fn = BLOCK_ABSTRACT_ORIGIN (block);
509 if (fn == NULL || TREE_CODE (fn) != FUNCTION_DECL)
510 return NULL_TREE;
512 if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
513 || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
515 if (!check_clones)
516 return NULL_TREE;
518 /* Watch for clones where we constant propagated the first
519 argument (pointer to the instance). */
520 fn = DECL_ABSTRACT_ORIGIN (fn);
521 if (!fn
522 || TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
523 || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
524 return NULL_TREE;
527 if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
528 return NULL_TREE;
530 return fn;
534 /* We know that the instance is stored in variable or parameter
535 (not dynamically allocated) and we want to disprove the fact
536 that it may be in construction at invocation of CALL.
538 BASE represents memory location where instance is stored.
539 If BASE is NULL, it is assumed to be global memory.
540 OUTER_TYPE is known type of the instance or NULL if not
541 known.
543 For the variable to be in construction we actually need to
544 be in constructor of corresponding global variable or
545 the inline stack of CALL must contain the constructor.
546 Check this condition. This check works safely only before
547 IPA passes, because inline stacks may become out of date
548 later. */
550 bool
551 decl_maybe_in_construction_p (tree base, tree outer_type,
552 gimple call, tree function)
554 if (outer_type)
555 outer_type = TYPE_MAIN_VARIANT (outer_type);
556 gcc_assert (!base || DECL_P (base));
558 /* After inlining the code unification optimizations may invalidate
559 inline stacks. Also we need to give up on global variables after
560 IPA, because addresses of these may have been propagated to their
561 constructors. */
562 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
563 return true;
565 /* Pure functions can not do any changes on the dynamic type;
566 that require writting to memory. */
567 if ((!base || !auto_var_in_fn_p (base, function))
568 && flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
569 return false;
571 bool check_clones = !base || is_global_var (base);
572 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
573 block = BLOCK_SUPERCONTEXT (block))
574 if (tree fn = inlined_polymorphic_ctor_dtor_block_p (block, check_clones))
576 tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
578 if (!outer_type || !types_odr_comparable (type, outer_type))
580 if (TREE_CODE (type) == RECORD_TYPE
581 && TYPE_BINFO (type)
582 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
583 return true;
585 else if (types_same_for_odr (type, outer_type))
586 return true;
589 if (!base || (TREE_CODE (base) == VAR_DECL && is_global_var (base)))
591 if (TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
592 || (!DECL_CXX_CONSTRUCTOR_P (function)
593 && !DECL_CXX_DESTRUCTOR_P (function)))
595 if (!DECL_ABSTRACT_ORIGIN (function))
596 return false;
597 /* Watch for clones where we constant propagated the first
598 argument (pointer to the instance). */
599 function = DECL_ABSTRACT_ORIGIN (function);
600 if (!function
601 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
602 || (!DECL_CXX_CONSTRUCTOR_P (function)
603 && !DECL_CXX_DESTRUCTOR_P (function)))
604 return false;
606 tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (function));
607 if (!outer_type || !types_odr_comparable (type, outer_type))
609 if (TREE_CODE (type) == RECORD_TYPE
610 && TYPE_BINFO (type)
611 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
612 return true;
614 else if (types_same_for_odr (type, outer_type))
615 return true;
617 return false;
620 /* Dump human readable context to F. If NEWLINE is true, it will be terminated
621 by a newline. */
623 void
624 ipa_polymorphic_call_context::dump (FILE *f, bool newline) const
626 fprintf (f, " ");
627 if (invalid)
628 fprintf (f, "Call is known to be undefined");
629 else
631 if (useless_p ())
632 fprintf (f, "nothing known");
633 if (outer_type || offset)
635 fprintf (f, "Outer type%s:", dynamic ? " (dynamic)":"");
636 print_generic_expr (f, outer_type, TDF_SLIM);
637 if (maybe_derived_type)
638 fprintf (f, " (or a derived type)");
639 if (maybe_in_construction)
640 fprintf (f, " (maybe in construction)");
641 fprintf (f, " offset " HOST_WIDE_INT_PRINT_DEC,
642 offset);
644 if (speculative_outer_type)
646 if (outer_type || offset)
647 fprintf (f, " ");
648 fprintf (f, "Speculative outer type:");
649 print_generic_expr (f, speculative_outer_type, TDF_SLIM);
650 if (speculative_maybe_derived_type)
651 fprintf (f, " (or a derived type)");
652 fprintf (f, " at offset " HOST_WIDE_INT_PRINT_DEC,
653 speculative_offset);
656 if (newline)
657 fprintf(f, "\n");
660 /* Print context to stderr. */
662 void
663 ipa_polymorphic_call_context::debug () const
665 dump (stderr);
668 /* Stream out the context to OB. */
670 void
671 ipa_polymorphic_call_context::stream_out (struct output_block *ob) const
673 struct bitpack_d bp = bitpack_create (ob->main_stream);
675 bp_pack_value (&bp, invalid, 1);
676 bp_pack_value (&bp, maybe_in_construction, 1);
677 bp_pack_value (&bp, maybe_derived_type, 1);
678 bp_pack_value (&bp, speculative_maybe_derived_type, 1);
679 bp_pack_value (&bp, dynamic, 1);
680 bp_pack_value (&bp, outer_type != NULL, 1);
681 bp_pack_value (&bp, offset != 0, 1);
682 bp_pack_value (&bp, speculative_outer_type != NULL, 1);
683 streamer_write_bitpack (&bp);
685 if (outer_type != NULL)
686 stream_write_tree (ob, outer_type, true);
687 if (offset)
688 streamer_write_hwi (ob, offset);
689 if (speculative_outer_type != NULL)
691 stream_write_tree (ob, speculative_outer_type, true);
692 streamer_write_hwi (ob, speculative_offset);
694 else
695 gcc_assert (!speculative_offset);
698 /* Stream in the context from IB and DATA_IN. */
700 void
701 ipa_polymorphic_call_context::stream_in (struct lto_input_block *ib,
702 struct data_in *data_in)
704 struct bitpack_d bp = streamer_read_bitpack (ib);
706 invalid = bp_unpack_value (&bp, 1);
707 maybe_in_construction = bp_unpack_value (&bp, 1);
708 maybe_derived_type = bp_unpack_value (&bp, 1);
709 speculative_maybe_derived_type = bp_unpack_value (&bp, 1);
710 dynamic = bp_unpack_value (&bp, 1);
711 bool outer_type_p = bp_unpack_value (&bp, 1);
712 bool offset_p = bp_unpack_value (&bp, 1);
713 bool speculative_outer_type_p = bp_unpack_value (&bp, 1);
715 if (outer_type_p)
716 outer_type = stream_read_tree (ib, data_in);
717 else
718 outer_type = NULL;
719 if (offset_p)
720 offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
721 else
722 offset = 0;
723 if (speculative_outer_type_p)
725 speculative_outer_type = stream_read_tree (ib, data_in);
726 speculative_offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
728 else
730 speculative_outer_type = NULL;
731 speculative_offset = 0;
735 /* Proudce polymorphic call context for call method of instance
736 that is located within BASE (that is assumed to be a decl) at offset OFF. */
738 void
739 ipa_polymorphic_call_context::set_by_decl (tree base, HOST_WIDE_INT off)
741 gcc_assert (DECL_P (base));
742 clear_speculation ();
744 if (!contains_polymorphic_type_p (TREE_TYPE (base)))
746 clear_outer_type ();
747 offset = off;
748 return;
750 outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (base));
751 offset = off;
752 /* Make very conservative assumption that all objects
753 may be in construction.
755 It is up to caller to revisit this via
756 get_dynamic_type or decl_maybe_in_construction_p. */
757 maybe_in_construction = true;
758 maybe_derived_type = false;
759 dynamic = false;
762 /* CST is an invariant (address of decl), try to get meaningful
763 polymorphic call context for polymorphic call of method
764 if instance of OTR_TYPE that is located at offset OFF of this invariant.
765 Return FALSE if nothing meaningful can be found. */
767 bool
768 ipa_polymorphic_call_context::set_by_invariant (tree cst,
769 tree otr_type,
770 HOST_WIDE_INT off)
772 HOST_WIDE_INT offset2, size, max_size;
773 tree base;
775 invalid = false;
776 off = 0;
777 clear_outer_type (otr_type);
779 if (TREE_CODE (cst) != ADDR_EXPR)
780 return false;
782 cst = TREE_OPERAND (cst, 0);
783 base = get_ref_base_and_extent (cst, &offset2, &size, &max_size);
784 if (!DECL_P (base) || max_size == -1 || max_size != size)
785 return false;
787 /* Only type inconsistent programs can have otr_type that is
788 not part of outer type. */
789 if (otr_type && !contains_type_p (TREE_TYPE (base), off, otr_type))
790 return false;
792 set_by_decl (base, off);
793 return true;
796 /* See if OP is SSA name initialized as a copy or by single assignment.
797 If so, walk the SSA graph up. Because simple PHI conditional is considered
798 copy, GLOBAL_VISITED may be used to avoid infinite loop walking the SSA
799 graph. */
801 static tree
802 walk_ssa_copies (tree op, hash_set<tree> **global_visited = NULL)
804 hash_set <tree> *visited = NULL;
805 STRIP_NOPS (op);
806 while (TREE_CODE (op) == SSA_NAME
807 && !SSA_NAME_IS_DEFAULT_DEF (op)
808 /* We might be called via fold_stmt during cfgcleanup where
809 SSA form need not be up-to-date. */
810 && !name_registered_for_update_p (op)
811 && (gimple_assign_single_p (SSA_NAME_DEF_STMT (op))
812 || gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI))
814 if (global_visited)
816 if (!*global_visited)
817 *global_visited = new hash_set<tree>;
818 if ((*global_visited)->add (op))
819 goto done;
821 else
823 if (!visited)
824 visited = new hash_set<tree>;
825 if (visited->add (op))
826 goto done;
828 /* Special case
829 if (ptr == 0)
830 ptr = 0;
831 else
832 ptr = ptr.foo;
833 This pattern is implicitly produced for casts to non-primary
834 bases. When doing context analysis, we do not really care
835 about the case pointer is NULL, becuase the call will be
836 undefined anyway. */
837 if (gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI)
839 gimple phi = SSA_NAME_DEF_STMT (op);
841 if (gimple_phi_num_args (phi) > 2)
842 goto done;
843 if (gimple_phi_num_args (phi) == 1)
844 op = gimple_phi_arg_def (phi, 0);
845 else if (integer_zerop (gimple_phi_arg_def (phi, 0)))
846 op = gimple_phi_arg_def (phi, 1);
847 else if (integer_zerop (gimple_phi_arg_def (phi, 1)))
848 op = gimple_phi_arg_def (phi, 0);
849 else
850 goto done;
852 else
854 if (gimple_assign_load_p (SSA_NAME_DEF_STMT (op)))
855 goto done;
856 op = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op));
858 STRIP_NOPS (op);
860 done:
861 if (visited)
862 delete (visited);
863 return op;
866 /* Create polymorphic call context from IP invariant CST.
867 This is typically &global_var.
868 OTR_TYPE specify type of polymorphic call or NULL if unknown, OFF
869 is offset of call. */
871 ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree cst,
872 tree otr_type,
873 HOST_WIDE_INT off)
875 clear_speculation ();
876 set_by_invariant (cst, otr_type, off);
879 /* Build context for pointer REF contained in FNDECL at statement STMT.
880 if INSTANCE is non-NULL, return pointer to the object described by
881 the context or DECL where context is contained in. */
883 ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl,
884 tree ref,
885 gimple stmt,
886 tree *instance)
888 tree otr_type = NULL;
889 tree base_pointer;
890 hash_set <tree> *visited = NULL;
892 if (TREE_CODE (ref) == OBJ_TYPE_REF)
894 otr_type = obj_type_ref_class (ref);
895 base_pointer = OBJ_TYPE_REF_OBJECT (ref);
897 else
898 base_pointer = ref;
900 /* Set up basic info in case we find nothing interesting in the analysis. */
901 clear_speculation ();
902 clear_outer_type (otr_type);
903 invalid = false;
905 /* Walk SSA for outer object. */
906 while (true)
908 base_pointer = walk_ssa_copies (base_pointer, &visited);
909 if (TREE_CODE (base_pointer) == ADDR_EXPR)
911 HOST_WIDE_INT size, max_size;
912 HOST_WIDE_INT offset2;
913 tree base = get_ref_base_and_extent (TREE_OPERAND (base_pointer, 0),
914 &offset2, &size, &max_size);
916 if (max_size != -1 && max_size == size)
917 combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)),
918 offset + offset2,
919 true,
920 NULL /* Do not change outer type. */);
922 /* If this is a varying address, punt. */
923 if ((TREE_CODE (base) == MEM_REF || DECL_P (base))
924 && max_size != -1
925 && max_size == size)
927 /* We found dereference of a pointer. Type of the pointer
928 and MEM_REF is meaningless, but we can look futher. */
929 if (TREE_CODE (base) == MEM_REF)
931 base_pointer = TREE_OPERAND (base, 0);
932 offset
933 += offset2 + mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
934 outer_type = NULL;
936 /* We found base object. In this case the outer_type
937 is known. */
938 else if (DECL_P (base))
940 if (visited)
941 delete (visited);
942 /* Only type inconsistent programs can have otr_type that is
943 not part of outer type. */
944 if (otr_type
945 && !contains_type_p (TREE_TYPE (base),
946 offset + offset2, otr_type))
948 invalid = true;
949 if (instance)
950 *instance = base_pointer;
951 return;
953 set_by_decl (base, offset + offset2);
954 if (outer_type && maybe_in_construction && stmt)
955 maybe_in_construction
956 = decl_maybe_in_construction_p (base,
957 outer_type,
958 stmt,
959 fndecl);
960 if (instance)
961 *instance = base;
962 return;
964 else
965 break;
967 else
968 break;
970 else if (TREE_CODE (base_pointer) == POINTER_PLUS_EXPR
971 && tree_fits_uhwi_p (TREE_OPERAND (base_pointer, 1)))
973 offset += tree_to_shwi (TREE_OPERAND (base_pointer, 1))
974 * BITS_PER_UNIT;
975 base_pointer = TREE_OPERAND (base_pointer, 0);
977 else
978 break;
981 if (visited)
982 delete (visited);
984 /* Try to determine type of the outer object. */
985 if (TREE_CODE (base_pointer) == SSA_NAME
986 && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
987 && TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL)
989 /* See if parameter is THIS pointer of a method. */
990 if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE
991 && SSA_NAME_VAR (base_pointer) == DECL_ARGUMENTS (fndecl))
993 outer_type
994 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
995 gcc_assert (TREE_CODE (outer_type) == RECORD_TYPE
996 || TREE_CODE (outer_type) == UNION_TYPE);
998 /* Dynamic casting has possibly upcasted the type
999 in the hiearchy. In this case outer type is less
1000 informative than inner type and we should forget
1001 about it. */
1002 if ((otr_type
1003 && !contains_type_p (outer_type, offset,
1004 otr_type))
1005 || !contains_polymorphic_type_p (outer_type))
1007 outer_type = NULL;
1008 if (instance)
1009 *instance = base_pointer;
1010 return;
1013 dynamic = true;
1015 /* If the function is constructor or destructor, then
1016 the type is possibly in construction, but we know
1017 it is not derived type. */
1018 if (DECL_CXX_CONSTRUCTOR_P (fndecl)
1019 || DECL_CXX_DESTRUCTOR_P (fndecl))
1021 maybe_in_construction = true;
1022 maybe_derived_type = false;
1024 else
1026 maybe_derived_type = true;
1027 maybe_in_construction = false;
1029 if (instance)
1030 *instance = base_pointer;
1031 return;
1033 /* Non-PODs passed by value are really passed by invisible
1034 reference. In this case we also know the type of the
1035 object. */
1036 if (DECL_BY_REFERENCE (SSA_NAME_VAR (base_pointer)))
1038 outer_type
1039 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
1040 /* Only type inconsistent programs can have otr_type that is
1041 not part of outer type. */
1042 if (otr_type && !contains_type_p (outer_type, offset,
1043 otr_type))
1045 invalid = true;
1046 if (instance)
1047 *instance = base_pointer;
1048 return;
1050 /* Non-polymorphic types have no interest for us. */
1051 else if (!otr_type && !contains_polymorphic_type_p (outer_type))
1053 outer_type = NULL;
1054 if (instance)
1055 *instance = base_pointer;
1056 return;
1058 maybe_derived_type = false;
1059 maybe_in_construction = false;
1060 if (instance)
1061 *instance = base_pointer;
1062 return;
1066 tree base_type = TREE_TYPE (base_pointer);
1068 if (TREE_CODE (base_pointer) == SSA_NAME
1069 && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
1070 && !(TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL
1071 || TREE_CODE (SSA_NAME_VAR (base_pointer)) == RESULT_DECL))
1073 invalid = true;
1074 if (instance)
1075 *instance = base_pointer;
1076 return;
1078 if (TREE_CODE (base_pointer) == SSA_NAME
1079 && SSA_NAME_DEF_STMT (base_pointer)
1080 && gimple_assign_single_p (SSA_NAME_DEF_STMT (base_pointer)))
1081 base_type = TREE_TYPE (gimple_assign_rhs1
1082 (SSA_NAME_DEF_STMT (base_pointer)));
1084 if (base_type && POINTER_TYPE_P (base_type))
1085 combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base_type)),
1086 offset,
1087 true, NULL /* Do not change type here */);
1088 /* TODO: There are multiple ways to derive a type. For instance
1089 if BASE_POINTER is passed to an constructor call prior our refernece.
1090 We do not make this type of flow sensitive analysis yet. */
1091 if (instance)
1092 *instance = base_pointer;
1093 return;
1096 /* Structure to be passed in between detect_type_change and
1097 check_stmt_for_type_change. */
1099 struct type_change_info
1101 /* Offset into the object where there is the virtual method pointer we are
1102 looking for. */
1103 HOST_WIDE_INT offset;
1104 /* The declaration or SSA_NAME pointer of the base that we are checking for
1105 type change. */
1106 tree instance;
1107 /* The reference to virtual table pointer used. */
1108 tree vtbl_ptr_ref;
1109 tree otr_type;
1110 /* If we actually can tell the type that the object has changed to, it is
1111 stored in this field. Otherwise it remains NULL_TREE. */
1112 tree known_current_type;
1113 HOST_WIDE_INT known_current_offset;
1115 /* Set to true if dynamic type change has been detected. */
1116 bool type_maybe_changed;
1117 /* Set to true if multiple types have been encountered. known_current_type
1118 must be disregarded in that case. */
1119 bool multiple_types_encountered;
1120 /* Set to true if we possibly missed some dynamic type changes and we should
1121 consider the set to be speculative. */
1122 bool speculative;
1123 bool seen_unanalyzed_store;
1126 /* Return true if STMT is not call and can modify a virtual method table pointer.
1127 We take advantage of fact that vtable stores must appear within constructor
1128 and destructor functions. */
1130 static bool
1131 noncall_stmt_may_be_vtbl_ptr_store (gimple stmt)
1133 if (is_gimple_assign (stmt))
1135 tree lhs = gimple_assign_lhs (stmt);
1137 if (gimple_clobber_p (stmt))
1138 return false;
1139 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
1141 if (flag_strict_aliasing
1142 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
1143 return false;
1145 if (TREE_CODE (lhs) == COMPONENT_REF
1146 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
1147 return false;
1148 /* In the future we might want to use get_base_ref_and_offset to find
1149 if there is a field corresponding to the offset and if so, proceed
1150 almost like if it was a component ref. */
1154 /* Code unification may mess with inline stacks. */
1155 if (cfun->after_inlining)
1156 return true;
1158 /* Walk the inline stack and watch out for ctors/dtors.
1159 TODO: Maybe we can require the store to appear in toplevel
1160 block of CTOR/DTOR. */
1161 for (tree block = gimple_block (stmt); block && TREE_CODE (block) == BLOCK;
1162 block = BLOCK_SUPERCONTEXT (block))
1163 if (BLOCK_ABSTRACT_ORIGIN (block)
1164 && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) == FUNCTION_DECL)
1165 return inlined_polymorphic_ctor_dtor_block_p (block, false);
1166 return (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
1167 && (DECL_CXX_CONSTRUCTOR_P (current_function_decl)
1168 || DECL_CXX_DESTRUCTOR_P (current_function_decl)));
1171 /* If STMT can be proved to be an assignment to the virtual method table
1172 pointer of ANALYZED_OBJ and the type associated with the new table
1173 identified, return the type. Otherwise return NULL_TREE if type changes
1174 in unknown way or ERROR_MARK_NODE if type is unchanged. */
1176 static tree
1177 extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci,
1178 HOST_WIDE_INT *type_offset)
1180 HOST_WIDE_INT offset, size, max_size;
1181 tree lhs, rhs, base;
1183 if (!gimple_assign_single_p (stmt))
1184 return NULL_TREE;
1186 lhs = gimple_assign_lhs (stmt);
1187 rhs = gimple_assign_rhs1 (stmt);
1188 if (TREE_CODE (lhs) != COMPONENT_REF
1189 || !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
1191 if (dump_file)
1192 fprintf (dump_file, " LHS is not virtual table.\n");
1193 return NULL_TREE;
1196 if (tci->vtbl_ptr_ref && operand_equal_p (lhs, tci->vtbl_ptr_ref, 0))
1198 else
1200 base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
1201 if (DECL_P (tci->instance))
1203 if (base != tci->instance)
1205 if (dump_file)
1207 fprintf (dump_file, " base:");
1208 print_generic_expr (dump_file, base, TDF_SLIM);
1209 fprintf (dump_file, " does not match instance:");
1210 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1211 fprintf (dump_file, "\n");
1213 return NULL_TREE;
1216 else if (TREE_CODE (base) == MEM_REF)
1218 if (!operand_equal_p (tci->instance, TREE_OPERAND (base, 0), 0))
1220 if (dump_file)
1222 fprintf (dump_file, " base mem ref:");
1223 print_generic_expr (dump_file, base, TDF_SLIM);
1224 fprintf (dump_file, " does not match instance:");
1225 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1226 fprintf (dump_file, "\n");
1228 return NULL_TREE;
1230 if (!integer_zerop (TREE_OPERAND (base, 1)))
1232 if (!tree_fits_shwi_p (TREE_OPERAND (base, 1)))
1234 if (dump_file)
1236 fprintf (dump_file, " base mem ref:");
1237 print_generic_expr (dump_file, base, TDF_SLIM);
1238 fprintf (dump_file, " has non-representable offset:");
1239 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1240 fprintf (dump_file, "\n");
1242 return NULL_TREE;
1244 else
1245 offset += tree_to_shwi (TREE_OPERAND (base, 1)) * BITS_PER_UNIT;
1248 else if (!operand_equal_p (tci->instance, base, 0)
1249 || tci->offset)
1251 if (dump_file)
1253 fprintf (dump_file, " base:");
1254 print_generic_expr (dump_file, base, TDF_SLIM);
1255 fprintf (dump_file, " does not match instance:");
1256 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1257 fprintf (dump_file, " with offset %i\n", (int)tci->offset);
1259 return tci->offset > POINTER_SIZE ? error_mark_node : NULL_TREE;
1261 if (offset != tci->offset
1262 || size != POINTER_SIZE
1263 || max_size != POINTER_SIZE)
1265 if (dump_file)
1266 fprintf (dump_file, " wrong offset %i!=%i or size %i\n",
1267 (int)offset, (int)tci->offset, (int)size);
1268 return offset + POINTER_SIZE <= tci->offset
1269 || (max_size != -1
1270 && tci->offset + POINTER_SIZE > offset + max_size)
1271 ? error_mark_node : NULL;
1275 tree vtable;
1276 unsigned HOST_WIDE_INT offset2;
1278 if (!vtable_pointer_value_to_vtable (rhs, &vtable, &offset2))
1280 if (dump_file)
1281 fprintf (dump_file, " Failed to lookup binfo\n");
1282 return NULL;
1285 tree binfo = subbinfo_with_vtable_at_offset (TYPE_BINFO (DECL_CONTEXT (vtable)),
1286 offset2, vtable);
1287 if (!binfo)
1289 if (dump_file)
1290 fprintf (dump_file, " Construction vtable used\n");
1291 /* FIXME: We should suport construction contexts. */
1292 return NULL;
1295 *type_offset = tree_to_shwi (BINFO_OFFSET (binfo)) * BITS_PER_UNIT;
1296 return DECL_CONTEXT (vtable);
1299 /* Record dynamic type change of TCI to TYPE. */
1301 static void
1302 record_known_type (struct type_change_info *tci, tree type, HOST_WIDE_INT offset)
1304 if (dump_file)
1306 if (type)
1308 fprintf (dump_file, " Recording type: ");
1309 print_generic_expr (dump_file, type, TDF_SLIM);
1310 fprintf (dump_file, " at offset %i\n", (int)offset);
1312 else
1313 fprintf (dump_file, " Recording unknown type\n");
1316 /* If we found a constructor of type that is not polymorphic or
1317 that may contain the type in question as a field (not as base),
1318 restrict to the inner class first to make type matching bellow
1319 happier. */
1320 if (type
1321 && (offset
1322 || (TREE_CODE (type) != RECORD_TYPE
1323 || !TYPE_BINFO (type)
1324 || !polymorphic_type_binfo_p (TYPE_BINFO (type)))))
1326 ipa_polymorphic_call_context context;
1328 context.offset = offset;
1329 context.outer_type = type;
1330 context.maybe_in_construction = false;
1331 context.maybe_derived_type = false;
1332 context.dynamic = true;
1333 /* If we failed to find the inner type, we know that the call
1334 would be undefined for type produced here. */
1335 if (!context.restrict_to_inner_class (tci->otr_type))
1337 if (dump_file)
1338 fprintf (dump_file, " Ignoring; does not contain otr_type\n");
1339 return;
1341 /* Watch for case we reached an POD type and anticipate placement
1342 new. */
1343 if (!context.maybe_derived_type)
1345 type = context.outer_type;
1346 offset = context.offset;
1349 if (tci->type_maybe_changed
1350 && (!types_same_for_odr (type, tci->known_current_type)
1351 || offset != tci->known_current_offset))
1352 tci->multiple_types_encountered = true;
1353 tci->known_current_type = TYPE_MAIN_VARIANT (type);
1354 tci->known_current_offset = offset;
1355 tci->type_maybe_changed = true;
1358 /* Callback of walk_aliased_vdefs and a helper function for
1359 detect_type_change to check whether a particular statement may modify
1360 the virtual table pointer, and if possible also determine the new type of
1361 the (sub-)object. It stores its result into DATA, which points to a
1362 type_change_info structure. */
1364 static bool
1365 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
1367 gimple stmt = SSA_NAME_DEF_STMT (vdef);
1368 struct type_change_info *tci = (struct type_change_info *) data;
1369 tree fn;
1371 /* If we already gave up, just terminate the rest of walk. */
1372 if (tci->multiple_types_encountered)
1373 return true;
1375 if (is_gimple_call (stmt))
1377 if (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))
1378 return false;
1380 /* Check for a constructor call. */
1381 if ((fn = gimple_call_fndecl (stmt)) != NULL_TREE
1382 && DECL_CXX_CONSTRUCTOR_P (fn)
1383 && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
1384 && gimple_call_num_args (stmt))
1386 tree op = walk_ssa_copies (gimple_call_arg (stmt, 0));
1387 tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
1388 HOST_WIDE_INT offset = 0, size, max_size;
1390 if (dump_file)
1392 fprintf (dump_file, " Checking constructor call: ");
1393 print_gimple_stmt (dump_file, stmt, 0, 0);
1396 /* See if THIS parameter seems like instance pointer. */
1397 if (TREE_CODE (op) == ADDR_EXPR)
1399 op = get_ref_base_and_extent (TREE_OPERAND (op, 0),
1400 &offset, &size, &max_size);
1401 if (size != max_size || max_size == -1)
1403 tci->speculative = true;
1404 return false;
1406 if (op && TREE_CODE (op) == MEM_REF)
1408 if (!tree_fits_shwi_p (TREE_OPERAND (op, 1)))
1410 tci->speculative = true;
1411 return false;
1413 offset += tree_to_shwi (TREE_OPERAND (op, 1))
1414 * BITS_PER_UNIT;
1415 op = TREE_OPERAND (op, 0);
1417 else if (DECL_P (op))
1419 else
1421 tci->speculative = true;
1422 return false;
1424 op = walk_ssa_copies (op);
1426 if (operand_equal_p (op, tci->instance, 0)
1427 && TYPE_SIZE (type)
1428 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
1429 && tree_fits_shwi_p (TYPE_SIZE (type))
1430 && tree_to_shwi (TYPE_SIZE (type)) + offset > tci->offset)
1432 record_known_type (tci, type, tci->offset - offset);
1433 return true;
1436 /* Calls may possibly change dynamic type by placement new. Assume
1437 it will not happen, but make result speculative only. */
1438 if (dump_file)
1440 fprintf (dump_file, " Function call may change dynamic type:");
1441 print_gimple_stmt (dump_file, stmt, 0, 0);
1443 tci->speculative = true;
1444 return false;
1446 /* Check for inlined virtual table store. */
1447 else if (noncall_stmt_may_be_vtbl_ptr_store (stmt))
1449 tree type;
1450 HOST_WIDE_INT offset = 0;
1451 if (dump_file)
1453 fprintf (dump_file, " Checking vtbl store: ");
1454 print_gimple_stmt (dump_file, stmt, 0, 0);
1457 type = extr_type_from_vtbl_ptr_store (stmt, tci, &offset);
1458 if (type == error_mark_node)
1459 return false;
1460 gcc_assert (!type || TYPE_MAIN_VARIANT (type) == type);
1461 if (!type)
1463 if (dump_file)
1464 fprintf (dump_file, " Unanalyzed store may change type.\n");
1465 tci->seen_unanalyzed_store = true;
1466 tci->speculative = true;
1468 else
1469 record_known_type (tci, type, offset);
1470 return true;
1472 else
1473 return false;
1476 /* THIS is polymorphic call context obtained from get_polymorphic_context.
1477 OTR_OBJECT is pointer to the instance returned by OBJ_TYPE_REF_OBJECT.
1478 INSTANCE is pointer to the outer instance as returned by
1479 get_polymorphic_context. To avoid creation of temporary expressions,
1480 INSTANCE may also be an declaration of get_polymorphic_context found the
1481 value to be in static storage.
1483 If the type of instance is not fully determined
1484 (either OUTER_TYPE is unknown or MAYBE_IN_CONSTRUCTION/INCLUDE_DERIVED_TYPES
1485 is set), try to walk memory writes and find the actual construction of the
1486 instance.
1488 Return true if memory is unchanged from function entry.
1490 We do not include this analysis in the context analysis itself, because
1491 it needs memory SSA to be fully built and the walk may be expensive.
1492 So it is not suitable for use withing fold_stmt and similar uses. */
1494 bool
1495 ipa_polymorphic_call_context::get_dynamic_type (tree instance,
1496 tree otr_object,
1497 tree otr_type,
1498 gimple call)
1500 struct type_change_info tci;
1501 ao_ref ao;
1502 bool function_entry_reached = false;
1503 tree instance_ref = NULL;
1504 gimple stmt = call;
1505 /* Remember OFFSET before it is modified by restrict_to_inner_class.
1506 This is because we do not update INSTANCE when walking inwards. */
1507 HOST_WIDE_INT instance_offset = offset;
1509 if (otr_type)
1510 otr_type = TYPE_MAIN_VARIANT (otr_type);
1512 /* Walk into inner type. This may clear maybe_derived_type and save us
1513 from useless work. It also makes later comparsions with static type
1514 easier. */
1515 if (outer_type && otr_type)
1517 if (!restrict_to_inner_class (otr_type))
1518 return false;
1521 if (!maybe_in_construction && !maybe_derived_type)
1522 return false;
1524 /* We need to obtain refernce to virtual table pointer. It is better
1525 to look it up in the code rather than build our own. This require bit
1526 of pattern matching, but we end up verifying that what we found is
1527 correct.
1529 What we pattern match is:
1531 tmp = instance->_vptr.A; // vtbl ptr load
1532 tmp2 = tmp[otr_token]; // vtable lookup
1533 OBJ_TYPE_REF(tmp2;instance->0) (instance);
1535 We want to start alias oracle walk from vtbl pointer load,
1536 but we may not be able to identify it, for example, when PRE moved the
1537 load around. */
1539 if (gimple_code (call) == GIMPLE_CALL)
1541 tree ref = gimple_call_fn (call);
1542 HOST_WIDE_INT offset2, size, max_size;
1544 if (TREE_CODE (ref) == OBJ_TYPE_REF)
1546 ref = OBJ_TYPE_REF_EXPR (ref);
1547 ref = walk_ssa_copies (ref);
1549 /* If call target is already known, no need to do the expensive
1550 memory walk. */
1551 if (is_gimple_min_invariant (ref))
1552 return false;
1554 /* Check if definition looks like vtable lookup. */
1555 if (TREE_CODE (ref) == SSA_NAME
1556 && !SSA_NAME_IS_DEFAULT_DEF (ref)
1557 && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref))
1558 && TREE_CODE (gimple_assign_rhs1
1559 (SSA_NAME_DEF_STMT (ref))) == MEM_REF)
1561 ref = get_base_address
1562 (TREE_OPERAND (gimple_assign_rhs1
1563 (SSA_NAME_DEF_STMT (ref)), 0));
1564 ref = walk_ssa_copies (ref);
1565 /* Find base address of the lookup and see if it looks like
1566 vptr load. */
1567 if (TREE_CODE (ref) == SSA_NAME
1568 && !SSA_NAME_IS_DEFAULT_DEF (ref)
1569 && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref)))
1571 tree ref_exp = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (ref));
1572 tree base_ref = get_ref_base_and_extent
1573 (ref_exp, &offset2, &size, &max_size);
1575 /* Finally verify that what we found looks like read from
1576 OTR_OBJECT or from INSTANCE with offset OFFSET. */
1577 if (base_ref
1578 && ((TREE_CODE (base_ref) == MEM_REF
1579 && ((offset2 == instance_offset
1580 && TREE_OPERAND (base_ref, 0) == instance)
1581 || (!offset2
1582 && TREE_OPERAND (base_ref, 0)
1583 == otr_object)))
1584 || (DECL_P (instance) && base_ref == instance
1585 && offset2 == instance_offset)))
1587 stmt = SSA_NAME_DEF_STMT (ref);
1588 instance_ref = ref_exp;
1595 /* If we failed to look up the refernece in code, build our own. */
1596 if (!instance_ref)
1598 /* If the statement in question does not use memory, we can't tell
1599 anything. */
1600 if (!gimple_vuse (stmt))
1601 return false;
1602 ao_ref_init_from_ptr_and_size (&ao, otr_object, NULL);
1604 else
1605 /* Otherwise use the real reference. */
1606 ao_ref_init (&ao, instance_ref);
1608 /* We look for vtbl pointer read. */
1609 ao.size = POINTER_SIZE;
1610 ao.max_size = ao.size;
1611 /* We are looking for stores to vptr pointer within the instance of
1612 outer type.
1613 TODO: The vptr pointer type is globally known, we probably should
1614 keep it and do that even when otr_type is unknown. */
1615 if (otr_type)
1617 ao.base_alias_set
1618 = get_alias_set (outer_type ? outer_type : otr_type);
1619 ao.ref_alias_set
1620 = get_alias_set (TREE_TYPE (BINFO_VTABLE (TYPE_BINFO (otr_type))));
1623 if (dump_file)
1625 fprintf (dump_file, "Determining dynamic type for call: ");
1626 print_gimple_stmt (dump_file, call, 0, 0);
1627 fprintf (dump_file, " Starting walk at: ");
1628 print_gimple_stmt (dump_file, stmt, 0, 0);
1629 fprintf (dump_file, " instance pointer: ");
1630 print_generic_expr (dump_file, otr_object, TDF_SLIM);
1631 fprintf (dump_file, " Outer instance pointer: ");
1632 print_generic_expr (dump_file, instance, TDF_SLIM);
1633 fprintf (dump_file, " offset: %i (bits)", (int)offset);
1634 fprintf (dump_file, " vtbl reference: ");
1635 print_generic_expr (dump_file, instance_ref, TDF_SLIM);
1636 fprintf (dump_file, "\n");
1639 tci.offset = offset;
1640 tci.instance = instance;
1641 tci.vtbl_ptr_ref = instance_ref;
1642 gcc_assert (TREE_CODE (instance) != MEM_REF);
1643 tci.known_current_type = NULL_TREE;
1644 tci.known_current_offset = 0;
1645 tci.otr_type = otr_type;
1646 tci.type_maybe_changed = false;
1647 tci.multiple_types_encountered = false;
1648 tci.speculative = false;
1649 tci.seen_unanalyzed_store = false;
1651 walk_aliased_vdefs (&ao, gimple_vuse (stmt), check_stmt_for_type_change,
1652 &tci, NULL, &function_entry_reached);
1654 /* If we did not find any type changing statements, we may still drop
1655 maybe_in_construction flag if the context already have outer type.
1657 Here we make special assumptions about both constructors and
1658 destructors which are all the functions that are allowed to alter the
1659 VMT pointers. It assumes that destructors begin with assignment into
1660 all VMT pointers and that constructors essentially look in the
1661 following way:
1663 1) The very first thing they do is that they call constructors of
1664 ancestor sub-objects that have them.
1666 2) Then VMT pointers of this and all its ancestors is set to new
1667 values corresponding to the type corresponding to the constructor.
1669 3) Only afterwards, other stuff such as constructor of member
1670 sub-objects and the code written by the user is run. Only this may
1671 include calling virtual functions, directly or indirectly.
1673 4) placement new can not be used to change type of non-POD statically
1674 allocated variables.
1676 There is no way to call a constructor of an ancestor sub-object in any
1677 other way.
1679 This means that we do not have to care whether constructors get the
1680 correct type information because they will always change it (in fact,
1681 if we define the type to be given by the VMT pointer, it is undefined).
1683 The most important fact to derive from the above is that if, for some
1684 statement in the section 3, we try to detect whether the dynamic type
1685 has changed, we can safely ignore all calls as we examine the function
1686 body backwards until we reach statements in section 2 because these
1687 calls cannot be ancestor constructors or destructors (if the input is
1688 not bogus) and so do not change the dynamic type (this holds true only
1689 for automatically allocated objects but at the moment we devirtualize
1690 only these). We then must detect that statements in section 2 change
1691 the dynamic type and can try to derive the new type. That is enough
1692 and we can stop, we will never see the calls into constructors of
1693 sub-objects in this code.
1695 Therefore if the static outer type was found (outer_type)
1696 we can safely ignore tci.speculative that is set on calls and give up
1697 only if there was dyanmic type store that may affect given variable
1698 (seen_unanalyzed_store) */
1700 if (!tci.type_maybe_changed
1701 || (outer_type
1702 && !dynamic
1703 && !tci.seen_unanalyzed_store
1704 && !tci.multiple_types_encountered
1705 && offset == tci.offset
1706 && types_same_for_odr (tci.known_current_type,
1707 outer_type)))
1709 if (!outer_type || tci.seen_unanalyzed_store)
1710 return false;
1711 if (maybe_in_construction)
1712 maybe_in_construction = false;
1713 if (dump_file)
1714 fprintf (dump_file, " No dynamic type change found.\n");
1715 return true;
1718 if (tci.known_current_type
1719 && !function_entry_reached
1720 && !tci.multiple_types_encountered)
1722 if (!tci.speculative)
1724 outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
1725 offset = tci.known_current_offset;
1726 dynamic = true;
1727 maybe_in_construction = false;
1728 maybe_derived_type = false;
1729 if (dump_file)
1730 fprintf (dump_file, " Determined dynamic type.\n");
1732 else if (!speculative_outer_type
1733 || speculative_maybe_derived_type)
1735 speculative_outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
1736 speculative_offset = tci.known_current_offset;
1737 speculative_maybe_derived_type = false;
1738 if (dump_file)
1739 fprintf (dump_file, " Determined speculative dynamic type.\n");
1742 else if (dump_file)
1744 fprintf (dump_file, " Found multiple types%s%s\n",
1745 function_entry_reached ? " (function entry reached)" : "",
1746 function_entry_reached ? " (multiple types encountered)" : "");
1749 return false;
1752 /* See if speculation given by SPEC_OUTER_TYPE, SPEC_OFFSET and SPEC_MAYBE_DERIVED_TYPE
1753 seems consistent (and useful) with what we already have in the non-speculative context. */
1755 bool
1756 ipa_polymorphic_call_context::speculation_consistent_p (tree spec_outer_type,
1757 HOST_WIDE_INT spec_offset,
1758 bool spec_maybe_derived_type,
1759 tree otr_type) const
1761 if (!flag_devirtualize_speculatively)
1762 return false;
1764 /* Non-polymorphic types are useless for deriving likely polymorphic
1765 call targets. */
1766 if (!spec_outer_type || !contains_polymorphic_type_p (spec_outer_type))
1767 return false;
1769 /* If we know nothing, speculation is always good. */
1770 if (!outer_type)
1771 return true;
1773 /* Speculation is only useful to avoid derived types.
1774 This is not 100% true for placement new, where the outer context may
1775 turn out to be useless, but ignore these for now. */
1776 if (!maybe_derived_type)
1777 return false;
1779 /* If types agrees, speculation is consistent, but it makes sense only
1780 when it says something new. */
1781 if (types_must_be_same_for_odr (spec_outer_type, outer_type))
1782 return maybe_derived_type && !spec_maybe_derived_type;
1784 /* If speculation does not contain the type in question, ignore it. */
1785 if (otr_type
1786 && !contains_type_p (spec_outer_type, spec_offset, otr_type, false, true))
1787 return false;
1789 /* If outer type already contains speculation as a filed,
1790 it is useless. We already know from OUTER_TYPE
1791 SPEC_TYPE and that it is not in the construction. */
1792 if (contains_type_p (outer_type, offset - spec_offset,
1793 spec_outer_type, false, false))
1794 return false;
1796 /* If speculative outer type is not more specified than outer
1797 type, just give up.
1798 We can only decide this safely if we can compare types with OUTER_TYPE.
1800 if ((!in_lto_p || odr_type_p (outer_type))
1801 && !contains_type_p (spec_outer_type,
1802 spec_offset - offset,
1803 outer_type, false))
1804 return false;
1805 return true;
1808 /* Improve THIS with speculation described by NEW_OUTER_TYPE, NEW_OFFSET,
1809 NEW_MAYBE_DERIVED_TYPE
1810 If OTR_TYPE is set, assume the context is used with OTR_TYPE. */
1812 bool
1813 ipa_polymorphic_call_context::combine_speculation_with
1814 (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
1815 tree otr_type)
1817 if (!new_outer_type)
1818 return false;
1820 /* restrict_to_inner_class may eliminate wrong speculation making our job
1821 easeier. */
1822 if (otr_type)
1823 restrict_to_inner_class (otr_type);
1825 if (!speculation_consistent_p (new_outer_type, new_offset,
1826 new_maybe_derived_type, otr_type))
1827 return false;
1829 /* New speculation is a win in case we have no speculation or new
1830 speculation does not consider derivations. */
1831 if (!speculative_outer_type
1832 || (speculative_maybe_derived_type
1833 && !new_maybe_derived_type))
1835 speculative_outer_type = new_outer_type;
1836 speculative_offset = new_offset;
1837 speculative_maybe_derived_type = new_maybe_derived_type;
1838 return true;
1840 else if (types_must_be_same_for_odr (speculative_outer_type,
1841 new_outer_type))
1843 if (speculative_offset != new_offset)
1845 /* OK we have two contexts that seems valid but they disagree,
1846 just give up.
1848 This is not a lattice operation, so we may want to drop it later. */
1849 if (dump_file && (dump_flags & TDF_DETAILS))
1850 fprintf (dump_file,
1851 "Speculative outer types match, "
1852 "offset mismatch -> invalid speculation\n");
1853 clear_speculation ();
1854 return true;
1856 else
1858 if (speculative_maybe_derived_type && !new_maybe_derived_type)
1860 speculative_maybe_derived_type = false;
1861 return true;
1863 else
1864 return false;
1867 /* Choose type that contains the other. This one either contains the outer
1868 as a field (thus giving exactly one target) or is deeper in the type
1869 hiearchy. */
1870 else if (speculative_outer_type
1871 && speculative_maybe_derived_type
1872 && (new_offset > speculative_offset
1873 || (new_offset == speculative_offset
1874 && contains_type_p (new_outer_type,
1875 0, speculative_outer_type, false))))
1877 tree old_outer_type = speculative_outer_type;
1878 HOST_WIDE_INT old_offset = speculative_offset;
1879 bool old_maybe_derived_type = speculative_maybe_derived_type;
1881 speculative_outer_type = new_outer_type;
1882 speculative_offset = new_offset;
1883 speculative_maybe_derived_type = new_maybe_derived_type;
1885 if (otr_type)
1886 restrict_to_inner_class (otr_type);
1888 /* If the speculation turned out to make no sense, revert to sensible
1889 one. */
1890 if (!speculative_outer_type)
1892 speculative_outer_type = old_outer_type;
1893 speculative_offset = old_offset;
1894 speculative_maybe_derived_type = old_maybe_derived_type;
1895 return false;
1897 return (old_offset != speculative_offset
1898 || old_maybe_derived_type != speculative_maybe_derived_type
1899 || types_must_be_same_for_odr (speculative_outer_type,
1900 new_outer_type));
1902 return false;
1905 /* Make speculation less specific so
1906 NEW_OUTER_TYPE, NEW_OFFSET, NEW_MAYBE_DERIVED_TYPE is also included.
1907 If OTR_TYPE is set, assume the context is used with OTR_TYPE. */
1909 bool
1910 ipa_polymorphic_call_context::meet_speculation_with
1911 (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
1912 tree otr_type)
1914 if (!new_outer_type && speculative_outer_type)
1916 clear_speculation ();
1917 return true;
1920 /* restrict_to_inner_class may eliminate wrong speculation making our job
1921 easeier. */
1922 if (otr_type)
1923 restrict_to_inner_class (otr_type);
1925 if (!speculative_outer_type
1926 || !speculation_consistent_p (speculative_outer_type,
1927 speculative_offset,
1928 speculative_maybe_derived_type,
1929 otr_type))
1930 return false;
1932 if (!speculation_consistent_p (new_outer_type, new_offset,
1933 new_maybe_derived_type, otr_type))
1935 clear_speculation ();
1936 return true;
1939 else if (types_must_be_same_for_odr (speculative_outer_type,
1940 new_outer_type))
1942 if (speculative_offset != new_offset)
1944 clear_speculation ();
1945 return true;
1947 else
1949 if (!speculative_maybe_derived_type && new_maybe_derived_type)
1951 speculative_maybe_derived_type = true;
1952 return true;
1954 else
1955 return false;
1958 /* See if one type contains the other as a field (not base). */
1959 else if (contains_type_p (new_outer_type, new_offset - speculative_offset,
1960 speculative_outer_type, false, false))
1961 return false;
1962 else if (contains_type_p (speculative_outer_type,
1963 speculative_offset - new_offset,
1964 new_outer_type, false, false))
1966 speculative_outer_type = new_outer_type;
1967 speculative_offset = new_offset;
1968 speculative_maybe_derived_type = new_maybe_derived_type;
1969 return true;
1971 /* See if OUTER_TYPE is base of CTX.OUTER_TYPE. */
1972 else if (contains_type_p (new_outer_type,
1973 new_offset - speculative_offset,
1974 speculative_outer_type, false, true))
1976 if (!speculative_maybe_derived_type)
1978 speculative_maybe_derived_type = true;
1979 return true;
1981 return false;
1983 /* See if CTX.OUTER_TYPE is base of OUTER_TYPE. */
1984 else if (contains_type_p (speculative_outer_type,
1985 speculative_offset - new_offset, new_outer_type, false, true))
1987 speculative_outer_type = new_outer_type;
1988 speculative_offset = new_offset;
1989 speculative_maybe_derived_type = true;
1990 return true;
1992 else
1994 if (dump_file && (dump_flags & TDF_DETAILS))
1995 fprintf (dump_file, "Giving up on speculative meet\n");
1996 clear_speculation ();
1997 return true;
2001 /* Assume that both THIS and a given context is valid and strenghten THIS
2002 if possible. Return true if any strenghtening was made.
2003 If actual type the context is being used in is known, OTR_TYPE should be
2004 set accordingly. This improves quality of combined result. */
2006 bool
2007 ipa_polymorphic_call_context::combine_with (ipa_polymorphic_call_context ctx,
2008 tree otr_type)
2010 bool updated = false;
2012 if (ctx.useless_p () || invalid)
2013 return false;
2015 /* Restricting context to inner type makes merging easier, however do not
2016 do that unless we know how the context is used (OTR_TYPE is non-NULL) */
2017 if (otr_type && !invalid && !ctx.invalid)
2019 restrict_to_inner_class (otr_type);
2020 ctx.restrict_to_inner_class (otr_type);
2021 if(invalid)
2022 return false;
2025 if (dump_file && (dump_flags & TDF_DETAILS))
2027 fprintf (dump_file, "Polymorphic call context combine:");
2028 dump (dump_file);
2029 fprintf (dump_file, "With context: ");
2030 ctx.dump (dump_file);
2031 if (otr_type)
2033 fprintf (dump_file, "To be used with type: ");
2034 print_generic_expr (dump_file, otr_type, TDF_SLIM);
2035 fprintf (dump_file, "\n");
2039 /* If call is known to be invalid, we are done. */
2040 if (ctx.invalid)
2042 if (dump_file && (dump_flags & TDF_DETAILS))
2043 fprintf (dump_file, "-> Invalid context\n");
2044 goto invalidate;
2047 if (!ctx.outer_type)
2049 else if (!outer_type)
2051 outer_type = ctx.outer_type;
2052 offset = ctx.offset;
2053 dynamic = ctx.dynamic;
2054 maybe_in_construction = ctx.maybe_in_construction;
2055 maybe_derived_type = ctx.maybe_derived_type;
2056 updated = true;
2058 /* If types are known to be same, merging is quite easy. */
2059 else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
2061 if (offset != ctx.offset
2062 && TYPE_SIZE (outer_type)
2063 && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
2065 if (dump_file && (dump_flags & TDF_DETAILS))
2066 fprintf (dump_file, "Outer types match, offset mismatch -> invalid\n");
2067 clear_speculation ();
2068 clear_outer_type ();
2069 invalid = true;
2070 return true;
2072 if (dump_file && (dump_flags & TDF_DETAILS))
2073 fprintf (dump_file, "Outer types match, merging flags\n");
2074 if (maybe_in_construction && !ctx.maybe_in_construction)
2076 updated = true;
2077 maybe_in_construction = false;
2079 if (maybe_derived_type && !ctx.maybe_derived_type)
2081 updated = true;
2082 maybe_derived_type = false;
2084 if (dynamic && !ctx.dynamic)
2086 updated = true;
2087 dynamic = false;
2090 /* If we know the type precisely, there is not much to improve. */
2091 else if (!maybe_derived_type && !maybe_in_construction
2092 && !ctx.maybe_derived_type && !ctx.maybe_in_construction)
2094 /* It may be easy to check if second context permits the first
2095 and set INVALID otherwise. This is not easy to do in general;
2096 contains_type_p may return false negatives for non-comparable
2097 types.
2099 If OTR_TYPE is known, we however can expect that
2100 restrict_to_inner_class should have discovered the same base
2101 type. */
2102 if (otr_type && !ctx.maybe_in_construction && !ctx.maybe_derived_type)
2104 if (dump_file && (dump_flags & TDF_DETAILS))
2105 fprintf (dump_file, "Contextes disagree -> invalid\n");
2106 goto invalidate;
2109 /* See if one type contains the other as a field (not base).
2110 In this case we want to choose the wider type, because it contains
2111 more information. */
2112 else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
2113 outer_type, false, false))
2115 if (dump_file && (dump_flags & TDF_DETAILS))
2116 fprintf (dump_file, "Second type contain the first as a field\n");
2118 if (maybe_derived_type)
2120 outer_type = ctx.outer_type;
2121 maybe_derived_type = ctx.maybe_derived_type;
2122 offset = ctx.offset;
2123 dynamic = ctx.dynamic;
2124 updated = true;
2127 /* If we do not know how the context is being used, we can
2128 not clear MAYBE_IN_CONSTRUCTION because it may be offseted
2129 to other component of OUTER_TYPE later and we know nothing
2130 about it. */
2131 if (otr_type && maybe_in_construction
2132 && !ctx.maybe_in_construction)
2134 maybe_in_construction = false;
2135 updated = true;
2138 else if (contains_type_p (outer_type, offset - ctx.offset,
2139 ctx.outer_type, false, false))
2141 if (dump_file && (dump_flags & TDF_DETAILS))
2142 fprintf (dump_file, "First type contain the second as a field\n");
2144 if (otr_type && maybe_in_construction
2145 && !ctx.maybe_in_construction)
2147 maybe_in_construction = false;
2148 updated = true;
2151 /* See if OUTER_TYPE is base of CTX.OUTER_TYPE. */
2152 else if (contains_type_p (ctx.outer_type,
2153 ctx.offset - offset, outer_type, false, true))
2155 if (dump_file && (dump_flags & TDF_DETAILS))
2156 fprintf (dump_file, "First type is base of second\n");
2157 if (!maybe_derived_type)
2159 if (!ctx.maybe_in_construction
2160 && types_odr_comparable (outer_type, ctx.outer_type))
2162 if (dump_file && (dump_flags & TDF_DETAILS))
2163 fprintf (dump_file, "Second context does not permit base -> invalid\n");
2164 goto invalidate;
2167 /* Pick variant deeper in the hiearchy. */
2168 else
2170 outer_type = ctx.outer_type;
2171 maybe_in_construction = ctx.maybe_in_construction;
2172 maybe_derived_type = ctx.maybe_derived_type;
2173 offset = ctx.offset;
2174 dynamic = ctx.dynamic;
2175 updated = true;
2178 /* See if CTX.OUTER_TYPE is base of OUTER_TYPE. */
2179 else if (contains_type_p (outer_type,
2180 offset - ctx.offset, ctx.outer_type, false, true))
2182 if (dump_file && (dump_flags & TDF_DETAILS))
2183 fprintf (dump_file, "Second type is base of first\n");
2184 if (!ctx.maybe_derived_type)
2186 if (!maybe_in_construction
2187 && types_odr_comparable (outer_type, ctx.outer_type))
2189 if (dump_file && (dump_flags & TDF_DETAILS))
2190 fprintf (dump_file, "First context does not permit base -> invalid\n");
2191 goto invalidate;
2193 /* Pick the base type. */
2194 else if (maybe_in_construction)
2196 outer_type = ctx.outer_type;
2197 maybe_in_construction = ctx.maybe_in_construction;
2198 maybe_derived_type = ctx.maybe_derived_type;
2199 offset = ctx.offset;
2200 dynamic = ctx.dynamic;
2201 updated = true;
2205 /* TODO handle merging using hiearchy. */
2206 else if (dump_file && (dump_flags & TDF_DETAILS))
2207 fprintf (dump_file, "Giving up on merge\n");
2209 updated |= combine_speculation_with (ctx.speculative_outer_type,
2210 ctx.speculative_offset,
2211 ctx.speculative_maybe_derived_type,
2212 otr_type);
2214 if (updated && dump_file && (dump_flags & TDF_DETAILS))
2216 fprintf (dump_file, "Updated as: ");
2217 dump (dump_file);
2218 fprintf (dump_file, "\n");
2220 return updated;
2222 invalidate:
2223 invalid = true;
2224 clear_speculation ();
2225 clear_outer_type ();
2226 return true;
2229 /* Take non-speculative info, merge it with speculative and clear speculation.
2230 Used when we no longer manage to keep track of actual outer type, but we
2231 think it is still there.
2233 If OTR_TYPE is set, the transformation can be done more effectively assuming
2234 that context is going to be used only that way. */
2236 void
2237 ipa_polymorphic_call_context::make_speculative (tree otr_type)
2239 tree spec_outer_type = outer_type;
2240 HOST_WIDE_INT spec_offset = offset;
2241 bool spec_maybe_derived_type = maybe_derived_type;
2243 if (invalid)
2245 invalid = false;
2246 clear_outer_type ();
2247 clear_speculation ();
2248 return;
2250 if (!outer_type)
2251 return;
2252 clear_outer_type ();
2253 combine_speculation_with (spec_outer_type, spec_offset,
2254 spec_maybe_derived_type,
2255 otr_type);
2258 /* Use when we can not track dynamic type change. This speculatively assume
2259 type change is not happening. */
2261 void
2262 ipa_polymorphic_call_context::possible_dynamic_type_change (bool in_poly_cdtor,
2263 tree otr_type)
2265 if (dynamic)
2266 make_speculative (otr_type);
2267 else if (in_poly_cdtor)
2268 maybe_in_construction = true;
2271 /* Return TRUE if this context conveys the same information as OTHER. */
2273 bool
2274 ipa_polymorphic_call_context::equal_to
2275 (const ipa_polymorphic_call_context &x) const
2277 if (useless_p ())
2278 return x.useless_p ();
2279 if (invalid)
2280 return x.invalid;
2281 if (x.useless_p () || x.invalid)
2282 return false;
2284 if (outer_type)
2286 if (!x.outer_type
2287 || !types_odr_comparable (outer_type, x.outer_type)
2288 || !types_same_for_odr (outer_type, x.outer_type)
2289 || offset != x.offset
2290 || maybe_in_construction != x.maybe_in_construction
2291 || maybe_derived_type != x.maybe_derived_type
2292 || dynamic != x.dynamic)
2293 return false;
2295 else if (x.outer_type)
2296 return false;
2299 if (speculative_outer_type
2300 && speculation_consistent_p (speculative_outer_type, speculative_offset,
2301 speculative_maybe_derived_type, NULL_TREE))
2303 if (!x.speculative_outer_type)
2304 return false;
2306 if (!types_odr_comparable (speculative_outer_type,
2307 x.speculative_outer_type)
2308 || !types_same_for_odr (speculative_outer_type,
2309 x.speculative_outer_type)
2310 || speculative_offset != x.speculative_offset
2311 || speculative_maybe_derived_type != x.speculative_maybe_derived_type)
2312 return false;
2314 else if (x.speculative_outer_type
2315 && x.speculation_consistent_p (x.speculative_outer_type,
2316 x.speculative_offset,
2317 x.speculative_maybe_derived_type,
2318 NULL))
2319 return false;
2321 return true;
2324 /* Modify context to be strictly less restrictive than CTX. */
2326 bool
2327 ipa_polymorphic_call_context::meet_with (ipa_polymorphic_call_context ctx,
2328 tree otr_type)
2330 bool updated = false;
2332 if (useless_p () || ctx.invalid)
2333 return false;
2335 /* Restricting context to inner type makes merging easier, however do not
2336 do that unless we know how the context is used (OTR_TYPE is non-NULL) */
2337 if (otr_type && !useless_p () && !ctx.useless_p ())
2339 restrict_to_inner_class (otr_type);
2340 ctx.restrict_to_inner_class (otr_type);
2341 if(invalid)
2342 return false;
2345 if (equal_to (ctx))
2346 return false;
2348 if (ctx.useless_p () || invalid)
2350 *this = ctx;
2351 return true;
2354 if (dump_file && (dump_flags & TDF_DETAILS))
2356 fprintf (dump_file, "Polymorphic call context meet:");
2357 dump (dump_file);
2358 fprintf (dump_file, "With context: ");
2359 ctx.dump (dump_file);
2360 if (otr_type)
2362 fprintf (dump_file, "To be used with type: ");
2363 print_generic_expr (dump_file, otr_type, TDF_SLIM);
2364 fprintf (dump_file, "\n");
2368 if (!dynamic && ctx.dynamic)
2370 dynamic = true;
2371 updated = true;
2374 /* If call is known to be invalid, we are done. */
2375 if (!outer_type)
2377 else if (!ctx.outer_type)
2379 clear_outer_type ();
2380 updated = true;
2382 /* If types are known to be same, merging is quite easy. */
2383 else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
2385 if (offset != ctx.offset
2386 && TYPE_SIZE (outer_type)
2387 && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
2389 if (dump_file && (dump_flags & TDF_DETAILS))
2390 fprintf (dump_file, "Outer types match, offset mismatch -> clearing\n");
2391 clear_outer_type ();
2392 return true;
2394 if (dump_file && (dump_flags & TDF_DETAILS))
2395 fprintf (dump_file, "Outer types match, merging flags\n");
2396 if (!maybe_in_construction && ctx.maybe_in_construction)
2398 updated = true;
2399 maybe_in_construction = true;
2401 if (!maybe_derived_type && ctx.maybe_derived_type)
2403 updated = true;
2404 maybe_derived_type = true;
2406 if (!dynamic && ctx.dynamic)
2408 updated = true;
2409 dynamic = true;
2412 /* See if one type contains the other as a field (not base). */
2413 else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
2414 outer_type, false, false))
2416 if (dump_file && (dump_flags & TDF_DETAILS))
2417 fprintf (dump_file, "Second type contain the first as a field\n");
2419 /* The second type is more specified, so we keep the first.
2420 We need to set DYNAMIC flag to avoid declaring context INVALID
2421 of OFFSET ends up being out of range. */
2422 if (!dynamic
2423 && (ctx.dynamic
2424 || (!otr_type
2425 && (!TYPE_SIZE (ctx.outer_type)
2426 || !TYPE_SIZE (outer_type)
2427 || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
2428 TYPE_SIZE (outer_type), 0)))))
2430 dynamic = true;
2431 updated = true;
2434 else if (contains_type_p (outer_type, offset - ctx.offset,
2435 ctx.outer_type, false, false))
2437 if (dump_file && (dump_flags & TDF_DETAILS))
2438 fprintf (dump_file, "First type contain the second as a field\n");
2440 if (!dynamic
2441 && (ctx.dynamic
2442 || (!otr_type
2443 && (!TYPE_SIZE (ctx.outer_type)
2444 || !TYPE_SIZE (outer_type)
2445 || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
2446 TYPE_SIZE (outer_type), 0)))))
2447 dynamic = true;
2448 outer_type = ctx.outer_type;
2449 offset = ctx.offset;
2450 dynamic = ctx.dynamic;
2451 maybe_in_construction = ctx.maybe_in_construction;
2452 maybe_derived_type = ctx.maybe_derived_type;
2453 updated = true;
2455 /* See if OUTER_TYPE is base of CTX.OUTER_TYPE. */
2456 else if (contains_type_p (ctx.outer_type,
2457 ctx.offset - offset, outer_type, false, true))
2459 if (dump_file && (dump_flags & TDF_DETAILS))
2460 fprintf (dump_file, "First type is base of second\n");
2461 if (!maybe_derived_type)
2463 maybe_derived_type = true;
2464 updated = true;
2466 if (!maybe_in_construction && ctx.maybe_in_construction)
2468 maybe_in_construction = true;
2469 updated = true;
2471 if (!dynamic && ctx.dynamic)
2473 dynamic = true;
2474 updated = true;
2477 /* See if CTX.OUTER_TYPE is base of OUTER_TYPE. */
2478 else if (contains_type_p (outer_type,
2479 offset - ctx.offset, ctx.outer_type, false, true))
2481 if (dump_file && (dump_flags & TDF_DETAILS))
2482 fprintf (dump_file, "Second type is base of first\n");
2483 outer_type = ctx.outer_type;
2484 offset = ctx.offset;
2485 updated = true;
2486 if (!maybe_derived_type)
2487 maybe_derived_type = true;
2488 if (!maybe_in_construction && ctx.maybe_in_construction)
2489 maybe_in_construction = true;
2490 if (!dynamic && ctx.dynamic)
2491 dynamic = true;
2493 /* TODO handle merging using hiearchy. */
2494 else
2496 if (dump_file && (dump_flags & TDF_DETAILS))
2497 fprintf (dump_file, "Giving up on meet\n");
2498 clear_outer_type ();
2499 updated = true;
2502 updated |= meet_speculation_with (ctx.speculative_outer_type,
2503 ctx.speculative_offset,
2504 ctx.speculative_maybe_derived_type,
2505 otr_type);
2507 if (updated && dump_file && (dump_flags & TDF_DETAILS))
2509 fprintf (dump_file, "Updated as: ");
2510 dump (dump_file);
2511 fprintf (dump_file, "\n");
2513 return updated;