* g++.dg/cpp/ucn-1.C: Fix typo.
[official-gcc.git] / gcc / ipa-polymorphic-call.c
bloba577ffab68dff59f815cefd80e7d1addf5fdb1a0
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 "backend.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "tree-pass.h"
29 #include "tree-ssa-operands.h"
30 #include "streamer-hooks.h"
31 #include "cgraph.h"
32 #include "data-streamer.h"
33 #include "diagnostic.h"
34 #include "alias.h"
35 #include "fold-const.h"
36 #include "calls.h"
37 #include "ipa-utils.h"
38 #include "tree-dfa.h"
39 #include "gimple-pretty-print.h"
40 #include "tree-into-ssa.h"
42 /* Return true when TYPE contains an polymorphic type and thus is interesting
43 for devirtualization machinery. */
45 static bool contains_type_p (tree, HOST_WIDE_INT, tree,
46 bool consider_placement_new = true,
47 bool consider_bases = true);
49 bool
50 contains_polymorphic_type_p (const_tree type)
52 type = TYPE_MAIN_VARIANT (type);
54 if (RECORD_OR_UNION_TYPE_P (type))
56 if (TYPE_BINFO (type)
57 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
58 return true;
59 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
60 if (TREE_CODE (fld) == FIELD_DECL
61 && !DECL_ARTIFICIAL (fld)
62 && contains_polymorphic_type_p (TREE_TYPE (fld)))
63 return true;
64 return false;
66 if (TREE_CODE (type) == ARRAY_TYPE)
67 return contains_polymorphic_type_p (TREE_TYPE (type));
68 return false;
71 /* Return true if it seems valid to use placement new to build EXPECTED_TYPE
72 at possition CUR_OFFSET within TYPE.
74 POD can be changed to an instance of a polymorphic type by
75 placement new. Here we play safe and assume that any
76 non-polymorphic type is POD. */
77 bool
78 possible_placement_new (tree type, tree expected_type,
79 HOST_WIDE_INT cur_offset)
81 if (cur_offset < 0)
82 return true;
83 return ((TREE_CODE (type) != RECORD_TYPE
84 || !TYPE_BINFO (type)
85 || cur_offset >= POINTER_SIZE
86 || !polymorphic_type_binfo_p (TYPE_BINFO (type)))
87 && (!TYPE_SIZE (type)
88 || !tree_fits_shwi_p (TYPE_SIZE (type))
89 || (cur_offset
90 + (expected_type ? tree_to_uhwi (TYPE_SIZE (expected_type))
91 : POINTER_SIZE)
92 <= tree_to_uhwi (TYPE_SIZE (type)))));
95 /* THIS->OUTER_TYPE is a type of memory object where object of OTR_TYPE
96 is contained at THIS->OFFSET. Walk the memory representation of
97 THIS->OUTER_TYPE and find the outermost class type that match
98 OTR_TYPE or contain OTR_TYPE as a base. Update THIS
99 to represent it.
101 If OTR_TYPE is NULL, just find outermost polymorphic type with
102 virtual table present at possition OFFSET.
104 For example when THIS represents type
105 class A
107 int a;
108 class B b;
110 and we look for type at offset sizeof(int), we end up with B and offset 0.
111 If the same is produced by multiple inheritance, we end up with A and offset
112 sizeof(int).
114 If we can not find corresponding class, give up by setting
115 THIS->OUTER_TYPE to OTR_TYPE and THIS->OFFSET to NULL.
116 Return true when lookup was sucesful.
118 When CONSIDER_PLACEMENT_NEW is false, reject contexts that may be made
119 valid only via alocation of new polymorphic type inside by means
120 of placement new.
122 When CONSIDER_BASES is false, only look for actual fields, not base types
123 of TYPE. */
125 bool
126 ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type,
127 bool consider_placement_new,
128 bool consider_bases)
130 tree type = outer_type;
131 HOST_WIDE_INT cur_offset = offset;
132 bool speculative = false;
133 bool size_unknown = false;
134 unsigned HOST_WIDE_INT otr_type_size = POINTER_SIZE;
136 /* Update OUTER_TYPE to match EXPECTED_TYPE if it is not set. */
137 if (!outer_type)
139 clear_outer_type (otr_type);
140 type = otr_type;
141 cur_offset = 0;
143 /* See if OFFSET points inside OUTER_TYPE. If it does not, we know
144 that the context is either invalid, or the instance type must be
145 derived from OUTER_TYPE.
147 Because the instance type may contain field whose type is of OUTER_TYPE,
148 we can not derive any effective information about it.
150 TODO: In the case we know all derrived types, we can definitely do better
151 here. */
152 else if (TYPE_SIZE (outer_type)
153 && tree_fits_shwi_p (TYPE_SIZE (outer_type))
154 && tree_to_shwi (TYPE_SIZE (outer_type)) >= 0
155 && tree_to_shwi (TYPE_SIZE (outer_type)) <= offset)
157 bool der = maybe_derived_type; /* clear_outer_type will reset it. */
158 bool dyn = dynamic;
159 clear_outer_type (otr_type);
160 type = otr_type;
161 cur_offset = 0;
163 /* If derived type is not allowed, we know that the context is invalid.
164 For dynamic types, we really do not have information about
165 size of the memory location. It is possible that completely
166 different type is stored after outer_type. */
167 if (!der && !dyn)
169 clear_speculation ();
170 invalid = true;
171 return false;
175 if (otr_type && TYPE_SIZE (otr_type)
176 && tree_fits_shwi_p (TYPE_SIZE (otr_type)))
177 otr_type_size = tree_to_uhwi (TYPE_SIZE (otr_type));
179 if (!type || offset < 0)
180 goto no_useful_type_info;
182 /* Find the sub-object the constant actually refers to and mark whether it is
183 an artificial one (as opposed to a user-defined one).
185 This loop is performed twice; first time for outer_type and second time
186 for speculative_outer_type. The second run has SPECULATIVE set. */
187 while (true)
189 unsigned HOST_WIDE_INT pos, size;
190 tree fld;
192 /* If we do not know size of TYPE, we need to be more conservative
193 about accepting cases where we can not find EXPECTED_TYPE.
194 Generally the types that do matter here are of constant size.
195 Size_unknown case should be very rare. */
196 if (TYPE_SIZE (type)
197 && tree_fits_shwi_p (TYPE_SIZE (type))
198 && tree_to_shwi (TYPE_SIZE (type)) >= 0)
199 size_unknown = false;
200 else
201 size_unknown = true;
203 /* On a match, just return what we found. */
204 if ((otr_type
205 && types_odr_comparable (type, otr_type)
206 && types_same_for_odr (type, otr_type))
207 || (!otr_type
208 && TREE_CODE (type) == RECORD_TYPE
209 && TYPE_BINFO (type)
210 && polymorphic_type_binfo_p (TYPE_BINFO (type))))
212 if (speculative)
214 /* If we did not match the offset, just give up on speculation. */
215 if (cur_offset != 0
216 /* Also check if speculation did not end up being same as
217 non-speculation. */
218 || (types_must_be_same_for_odr (speculative_outer_type,
219 outer_type)
220 && (maybe_derived_type
221 == speculative_maybe_derived_type)))
222 clear_speculation ();
223 return true;
225 else
227 /* If type is known to be final, do not worry about derived
228 types. Testing it here may help us to avoid speculation. */
229 if (otr_type && TREE_CODE (outer_type) == RECORD_TYPE
230 && (!in_lto_p || odr_type_p (outer_type))
231 && type_with_linkage_p (outer_type)
232 && type_known_to_have_no_derivations_p (outer_type))
233 maybe_derived_type = false;
235 /* Type can not contain itself on an non-zero offset. In that case
236 just give up. Still accept the case where size is now known.
237 Either the second copy may appear past the end of type or within
238 the non-POD buffer located inside the variably sized type
239 itself. */
240 if (cur_offset != 0)
241 goto no_useful_type_info;
242 /* If we determined type precisely or we have no clue on
243 speuclation, we are done. */
244 if (!maybe_derived_type || !speculative_outer_type
245 || !speculation_consistent_p (speculative_outer_type,
246 speculative_offset,
247 speculative_maybe_derived_type,
248 otr_type))
250 clear_speculation ();
251 return true;
253 /* Otherwise look into speculation now. */
254 else
256 speculative = true;
257 type = speculative_outer_type;
258 cur_offset = speculative_offset;
259 continue;
264 /* Walk fields and find corresponding on at OFFSET. */
265 if (TREE_CODE (type) == RECORD_TYPE)
267 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
269 if (TREE_CODE (fld) != FIELD_DECL)
270 continue;
272 pos = int_bit_position (fld);
273 if (pos > (unsigned HOST_WIDE_INT)cur_offset)
274 continue;
276 /* Do not consider vptr itself. Not even for placement new. */
277 if (!pos && DECL_ARTIFICIAL (fld)
278 && POINTER_TYPE_P (TREE_TYPE (fld))
279 && TYPE_BINFO (type)
280 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
281 continue;
283 if (!DECL_SIZE (fld) || !tree_fits_uhwi_p (DECL_SIZE (fld)))
284 goto no_useful_type_info;
285 size = tree_to_uhwi (DECL_SIZE (fld));
287 /* We can always skip types smaller than pointer size:
288 those can not contain a virtual table pointer.
290 Disqualifying fields that are too small to fit OTR_TYPE
291 saves work needed to walk them for no benefit.
292 Because of the way the bases are packed into a class, the
293 field's size may be smaller than type size, so it needs
294 to be done with a care. */
296 if (pos <= (unsigned HOST_WIDE_INT)cur_offset
297 && (pos + size) >= (unsigned HOST_WIDE_INT)cur_offset
298 + POINTER_SIZE
299 && (!otr_type
300 || !TYPE_SIZE (TREE_TYPE (fld))
301 || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (fld)))
302 || (pos + tree_to_uhwi (TYPE_SIZE (TREE_TYPE (fld))))
303 >= cur_offset + otr_type_size))
304 break;
307 if (!fld)
308 goto no_useful_type_info;
310 type = TYPE_MAIN_VARIANT (TREE_TYPE (fld));
311 cur_offset -= pos;
312 /* DECL_ARTIFICIAL represents a basetype. */
313 if (!DECL_ARTIFICIAL (fld))
315 if (!speculative)
317 outer_type = type;
318 offset = cur_offset;
319 /* As soon as we se an field containing the type,
320 we know we are not looking for derivations. */
321 maybe_derived_type = false;
323 else
325 speculative_outer_type = type;
326 speculative_offset = cur_offset;
327 speculative_maybe_derived_type = false;
330 else if (!consider_bases)
331 goto no_useful_type_info;
333 else if (TREE_CODE (type) == ARRAY_TYPE)
335 tree subtype = TYPE_MAIN_VARIANT (TREE_TYPE (type));
337 /* Give up if we don't know array field size.
338 Also give up on non-polymorphic types as they are used
339 as buffers for placement new. */
340 if (!TYPE_SIZE (subtype)
341 || !tree_fits_shwi_p (TYPE_SIZE (subtype))
342 || tree_to_shwi (TYPE_SIZE (subtype)) <= 0
343 || !contains_polymorphic_type_p (subtype))
344 goto no_useful_type_info;
346 HOST_WIDE_INT new_offset = cur_offset % tree_to_shwi (TYPE_SIZE (subtype));
348 /* We may see buffer for placement new. In this case the expected type
349 can be bigger than the subtype. */
350 if (TYPE_SIZE (subtype)
351 && (cur_offset + otr_type_size
352 > tree_to_uhwi (TYPE_SIZE (subtype))))
353 goto no_useful_type_info;
355 cur_offset = new_offset;
356 type = TYPE_MAIN_VARIANT (subtype);
357 if (!speculative)
359 outer_type = type;
360 offset = cur_offset;
361 maybe_derived_type = false;
363 else
365 speculative_outer_type = type;
366 speculative_offset = cur_offset;
367 speculative_maybe_derived_type = false;
370 /* Give up on anything else. */
371 else
373 no_useful_type_info:
374 if (maybe_derived_type && !speculative
375 && TREE_CODE (outer_type) == RECORD_TYPE
376 && TREE_CODE (otr_type) == RECORD_TYPE
377 && TYPE_BINFO (otr_type)
378 && !offset
379 && get_binfo_at_offset (TYPE_BINFO (otr_type), 0, outer_type))
381 clear_outer_type (otr_type);
382 if (!speculative_outer_type
383 || !speculation_consistent_p (speculative_outer_type,
384 speculative_offset,
385 speculative_maybe_derived_type,
386 otr_type))
387 clear_speculation ();
388 if (speculative_outer_type)
390 speculative = true;
391 type = speculative_outer_type;
392 cur_offset = speculative_offset;
394 else
395 return true;
397 /* We found no way to embedd EXPECTED_TYPE in TYPE.
398 We still permit two special cases - placement new and
399 the case of variadic types containing themselves. */
400 if (!speculative
401 && consider_placement_new
402 && (size_unknown || !type || maybe_derived_type
403 || possible_placement_new (type, otr_type, cur_offset)))
405 /* In these weird cases we want to accept the context.
406 In non-speculative run we have no useful outer_type info
407 (TODO: we may eventually want to record upper bound on the
408 type size that can be used to prune the walk),
409 but we still want to consider speculation that may
410 give useful info. */
411 if (!speculative)
413 clear_outer_type (otr_type);
414 if (!speculative_outer_type
415 || !speculation_consistent_p (speculative_outer_type,
416 speculative_offset,
417 speculative_maybe_derived_type,
418 otr_type))
419 clear_speculation ();
420 if (speculative_outer_type)
422 speculative = true;
423 type = speculative_outer_type;
424 cur_offset = speculative_offset;
426 else
427 return true;
429 else
431 clear_speculation ();
432 return true;
435 else
437 clear_speculation ();
438 if (speculative)
439 return true;
440 clear_outer_type (otr_type);
441 invalid = true;
442 return false;
448 /* Return true if OUTER_TYPE contains OTR_TYPE at OFFSET.
449 CONSIDER_PLACEMENT_NEW makes function to accept cases where OTR_TYPE can
450 be built within OUTER_TYPE by means of placement new. CONSIDER_BASES makes
451 function to accept cases where OTR_TYPE appears as base of OUTER_TYPE or as
452 base of one of fields of OUTER_TYPE. */
454 static bool
455 contains_type_p (tree outer_type, HOST_WIDE_INT offset,
456 tree otr_type,
457 bool consider_placement_new,
458 bool consider_bases)
460 ipa_polymorphic_call_context context;
462 /* Check that type is within range. */
463 if (offset < 0)
464 return false;
465 if (TYPE_SIZE (outer_type) && TYPE_SIZE (otr_type)
466 && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST
467 && TREE_CODE (TYPE_SIZE (otr_type)) == INTEGER_CST
468 && wi::ltu_p (wi::to_offset (TYPE_SIZE (outer_type)),
469 (wi::to_offset (TYPE_SIZE (otr_type)) + offset)))
470 return false;
472 context.offset = offset;
473 context.outer_type = TYPE_MAIN_VARIANT (outer_type);
474 context.maybe_derived_type = false;
475 context.dynamic = false;
476 return context.restrict_to_inner_class (otr_type, consider_placement_new,
477 consider_bases);
481 /* Return a FUNCTION_DECL if BLOCK represents a constructor or destructor.
482 If CHECK_CLONES is true, also check for clones of ctor/dtors. */
484 tree
485 inlined_polymorphic_ctor_dtor_block_p (tree block, bool check_clones)
487 tree fn = BLOCK_ABSTRACT_ORIGIN (block);
488 if (fn == NULL || TREE_CODE (fn) != FUNCTION_DECL)
489 return NULL_TREE;
491 if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
492 || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
494 if (!check_clones)
495 return NULL_TREE;
497 /* Watch for clones where we constant propagated the first
498 argument (pointer to the instance). */
499 fn = DECL_ABSTRACT_ORIGIN (fn);
500 if (!fn
501 || TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
502 || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
503 return NULL_TREE;
506 if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
507 return NULL_TREE;
509 return fn;
513 /* We know that the instance is stored in variable or parameter
514 (not dynamically allocated) and we want to disprove the fact
515 that it may be in construction at invocation of CALL.
517 BASE represents memory location where instance is stored.
518 If BASE is NULL, it is assumed to be global memory.
519 OUTER_TYPE is known type of the instance or NULL if not
520 known.
522 For the variable to be in construction we actually need to
523 be in constructor of corresponding global variable or
524 the inline stack of CALL must contain the constructor.
525 Check this condition. This check works safely only before
526 IPA passes, because inline stacks may become out of date
527 later. */
529 bool
530 decl_maybe_in_construction_p (tree base, tree outer_type,
531 gimple *call, tree function)
533 if (outer_type)
534 outer_type = TYPE_MAIN_VARIANT (outer_type);
535 gcc_assert (!base || DECL_P (base));
537 /* After inlining the code unification optimizations may invalidate
538 inline stacks. Also we need to give up on global variables after
539 IPA, because addresses of these may have been propagated to their
540 constructors. */
541 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
542 return true;
544 /* Pure functions can not do any changes on the dynamic type;
545 that require writting to memory. */
546 if ((!base || !auto_var_in_fn_p (base, function))
547 && flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
548 return false;
550 bool check_clones = !base || is_global_var (base);
551 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
552 block = BLOCK_SUPERCONTEXT (block))
553 if (tree fn = inlined_polymorphic_ctor_dtor_block_p (block, check_clones))
555 tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
557 if (!outer_type || !types_odr_comparable (type, outer_type))
559 if (TREE_CODE (type) == RECORD_TYPE
560 && TYPE_BINFO (type)
561 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
562 return true;
564 else if (types_same_for_odr (type, outer_type))
565 return true;
568 if (!base || (TREE_CODE (base) == VAR_DECL && is_global_var (base)))
570 if (TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
571 || (!DECL_CXX_CONSTRUCTOR_P (function)
572 && !DECL_CXX_DESTRUCTOR_P (function)))
574 if (!DECL_ABSTRACT_ORIGIN (function))
575 return false;
576 /* Watch for clones where we constant propagated the first
577 argument (pointer to the instance). */
578 function = DECL_ABSTRACT_ORIGIN (function);
579 if (!function
580 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
581 || (!DECL_CXX_CONSTRUCTOR_P (function)
582 && !DECL_CXX_DESTRUCTOR_P (function)))
583 return false;
585 tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (function));
586 if (!outer_type || !types_odr_comparable (type, outer_type))
588 if (TREE_CODE (type) == RECORD_TYPE
589 && TYPE_BINFO (type)
590 && polymorphic_type_binfo_p (TYPE_BINFO (type)))
591 return true;
593 else if (types_same_for_odr (type, outer_type))
594 return true;
596 return false;
599 /* Dump human readable context to F. If NEWLINE is true, it will be terminated
600 by a newline. */
602 void
603 ipa_polymorphic_call_context::dump (FILE *f, bool newline) const
605 fprintf (f, " ");
606 if (invalid)
607 fprintf (f, "Call is known to be undefined");
608 else
610 if (useless_p ())
611 fprintf (f, "nothing known");
612 if (outer_type || offset)
614 fprintf (f, "Outer type%s:", dynamic ? " (dynamic)":"");
615 print_generic_expr (f, outer_type, TDF_SLIM);
616 if (maybe_derived_type)
617 fprintf (f, " (or a derived type)");
618 if (maybe_in_construction)
619 fprintf (f, " (maybe in construction)");
620 fprintf (f, " offset " HOST_WIDE_INT_PRINT_DEC,
621 offset);
623 if (speculative_outer_type)
625 if (outer_type || offset)
626 fprintf (f, " ");
627 fprintf (f, "Speculative outer type:");
628 print_generic_expr (f, speculative_outer_type, TDF_SLIM);
629 if (speculative_maybe_derived_type)
630 fprintf (f, " (or a derived type)");
631 fprintf (f, " at offset " HOST_WIDE_INT_PRINT_DEC,
632 speculative_offset);
635 if (newline)
636 fprintf(f, "\n");
639 /* Print context to stderr. */
641 void
642 ipa_polymorphic_call_context::debug () const
644 dump (stderr);
647 /* Stream out the context to OB. */
649 void
650 ipa_polymorphic_call_context::stream_out (struct output_block *ob) const
652 struct bitpack_d bp = bitpack_create (ob->main_stream);
654 bp_pack_value (&bp, invalid, 1);
655 bp_pack_value (&bp, maybe_in_construction, 1);
656 bp_pack_value (&bp, maybe_derived_type, 1);
657 bp_pack_value (&bp, speculative_maybe_derived_type, 1);
658 bp_pack_value (&bp, dynamic, 1);
659 bp_pack_value (&bp, outer_type != NULL, 1);
660 bp_pack_value (&bp, offset != 0, 1);
661 bp_pack_value (&bp, speculative_outer_type != NULL, 1);
662 streamer_write_bitpack (&bp);
664 if (outer_type != NULL)
665 stream_write_tree (ob, outer_type, true);
666 if (offset)
667 streamer_write_hwi (ob, offset);
668 if (speculative_outer_type != NULL)
670 stream_write_tree (ob, speculative_outer_type, true);
671 streamer_write_hwi (ob, speculative_offset);
673 else
674 gcc_assert (!speculative_offset);
677 /* Stream in the context from IB and DATA_IN. */
679 void
680 ipa_polymorphic_call_context::stream_in (struct lto_input_block *ib,
681 struct data_in *data_in)
683 struct bitpack_d bp = streamer_read_bitpack (ib);
685 invalid = bp_unpack_value (&bp, 1);
686 maybe_in_construction = bp_unpack_value (&bp, 1);
687 maybe_derived_type = bp_unpack_value (&bp, 1);
688 speculative_maybe_derived_type = bp_unpack_value (&bp, 1);
689 dynamic = bp_unpack_value (&bp, 1);
690 bool outer_type_p = bp_unpack_value (&bp, 1);
691 bool offset_p = bp_unpack_value (&bp, 1);
692 bool speculative_outer_type_p = bp_unpack_value (&bp, 1);
694 if (outer_type_p)
695 outer_type = stream_read_tree (ib, data_in);
696 else
697 outer_type = NULL;
698 if (offset_p)
699 offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
700 else
701 offset = 0;
702 if (speculative_outer_type_p)
704 speculative_outer_type = stream_read_tree (ib, data_in);
705 speculative_offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
707 else
709 speculative_outer_type = NULL;
710 speculative_offset = 0;
714 /* Proudce polymorphic call context for call method of instance
715 that is located within BASE (that is assumed to be a decl) at offset OFF. */
717 void
718 ipa_polymorphic_call_context::set_by_decl (tree base, HOST_WIDE_INT off)
720 gcc_assert (DECL_P (base));
721 clear_speculation ();
723 if (!contains_polymorphic_type_p (TREE_TYPE (base)))
725 clear_outer_type ();
726 offset = off;
727 return;
729 outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (base));
730 offset = off;
731 /* Make very conservative assumption that all objects
732 may be in construction.
734 It is up to caller to revisit this via
735 get_dynamic_type or decl_maybe_in_construction_p. */
736 maybe_in_construction = true;
737 maybe_derived_type = false;
738 dynamic = false;
741 /* CST is an invariant (address of decl), try to get meaningful
742 polymorphic call context for polymorphic call of method
743 if instance of OTR_TYPE that is located at offset OFF of this invariant.
744 Return FALSE if nothing meaningful can be found. */
746 bool
747 ipa_polymorphic_call_context::set_by_invariant (tree cst,
748 tree otr_type,
749 HOST_WIDE_INT off)
751 HOST_WIDE_INT offset2, size, max_size;
752 bool reverse;
753 tree base;
755 invalid = false;
756 off = 0;
757 clear_outer_type (otr_type);
759 if (TREE_CODE (cst) != ADDR_EXPR)
760 return false;
762 cst = TREE_OPERAND (cst, 0);
763 base = get_ref_base_and_extent (cst, &offset2, &size, &max_size, &reverse);
764 if (!DECL_P (base) || max_size == -1 || max_size != size)
765 return false;
767 /* Only type inconsistent programs can have otr_type that is
768 not part of outer type. */
769 if (otr_type && !contains_type_p (TREE_TYPE (base), off, otr_type))
770 return false;
772 set_by_decl (base, off);
773 return true;
776 /* See if OP is SSA name initialized as a copy or by single assignment.
777 If so, walk the SSA graph up. Because simple PHI conditional is considered
778 copy, GLOBAL_VISITED may be used to avoid infinite loop walking the SSA
779 graph. */
781 static tree
782 walk_ssa_copies (tree op, hash_set<tree> **global_visited = NULL)
784 hash_set <tree> *visited = NULL;
785 STRIP_NOPS (op);
786 while (TREE_CODE (op) == SSA_NAME
787 && !SSA_NAME_IS_DEFAULT_DEF (op)
788 /* We might be called via fold_stmt during cfgcleanup where
789 SSA form need not be up-to-date. */
790 && !name_registered_for_update_p (op)
791 && (gimple_assign_single_p (SSA_NAME_DEF_STMT (op))
792 || gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI))
794 if (global_visited)
796 if (!*global_visited)
797 *global_visited = new hash_set<tree>;
798 if ((*global_visited)->add (op))
799 goto done;
801 else
803 if (!visited)
804 visited = new hash_set<tree>;
805 if (visited->add (op))
806 goto done;
808 /* Special case
809 if (ptr == 0)
810 ptr = 0;
811 else
812 ptr = ptr.foo;
813 This pattern is implicitly produced for casts to non-primary
814 bases. When doing context analysis, we do not really care
815 about the case pointer is NULL, becuase the call will be
816 undefined anyway. */
817 if (gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI)
819 gimple *phi = SSA_NAME_DEF_STMT (op);
821 if (gimple_phi_num_args (phi) > 2)
822 goto done;
823 if (gimple_phi_num_args (phi) == 1)
824 op = gimple_phi_arg_def (phi, 0);
825 else if (integer_zerop (gimple_phi_arg_def (phi, 0)))
826 op = gimple_phi_arg_def (phi, 1);
827 else if (integer_zerop (gimple_phi_arg_def (phi, 1)))
828 op = gimple_phi_arg_def (phi, 0);
829 else
830 goto done;
832 else
834 if (gimple_assign_load_p (SSA_NAME_DEF_STMT (op)))
835 goto done;
836 op = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op));
838 STRIP_NOPS (op);
840 done:
841 if (visited)
842 delete (visited);
843 return op;
846 /* Create polymorphic call context from IP invariant CST.
847 This is typically &global_var.
848 OTR_TYPE specify type of polymorphic call or NULL if unknown, OFF
849 is offset of call. */
851 ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree cst,
852 tree otr_type,
853 HOST_WIDE_INT off)
855 clear_speculation ();
856 set_by_invariant (cst, otr_type, off);
859 /* Build context for pointer REF contained in FNDECL at statement STMT.
860 if INSTANCE is non-NULL, return pointer to the object described by
861 the context or DECL where context is contained in. */
863 ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl,
864 tree ref,
865 gimple *stmt,
866 tree *instance)
868 tree otr_type = NULL;
869 tree base_pointer;
870 hash_set <tree> *visited = NULL;
872 if (TREE_CODE (ref) == OBJ_TYPE_REF)
874 otr_type = obj_type_ref_class (ref);
875 base_pointer = OBJ_TYPE_REF_OBJECT (ref);
877 else
878 base_pointer = ref;
880 /* Set up basic info in case we find nothing interesting in the analysis. */
881 clear_speculation ();
882 clear_outer_type (otr_type);
883 invalid = false;
885 /* Walk SSA for outer object. */
886 while (true)
888 base_pointer = walk_ssa_copies (base_pointer, &visited);
889 if (TREE_CODE (base_pointer) == ADDR_EXPR)
891 HOST_WIDE_INT size, max_size;
892 HOST_WIDE_INT offset2;
893 bool reverse;
894 tree base
895 = get_ref_base_and_extent (TREE_OPERAND (base_pointer, 0),
896 &offset2, &size, &max_size, &reverse);
898 if (max_size != -1 && max_size == size)
899 combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)),
900 offset + offset2,
901 true,
902 NULL /* Do not change outer type. */);
904 /* If this is a varying address, punt. */
905 if ((TREE_CODE (base) == MEM_REF || DECL_P (base))
906 && max_size != -1
907 && max_size == size)
909 /* We found dereference of a pointer. Type of the pointer
910 and MEM_REF is meaningless, but we can look futher. */
911 if (TREE_CODE (base) == MEM_REF)
913 base_pointer = TREE_OPERAND (base, 0);
914 offset
915 += offset2 + mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
916 outer_type = NULL;
918 /* We found base object. In this case the outer_type
919 is known. */
920 else if (DECL_P (base))
922 if (visited)
923 delete (visited);
924 /* Only type inconsistent programs can have otr_type that is
925 not part of outer type. */
926 if (otr_type
927 && !contains_type_p (TREE_TYPE (base),
928 offset + offset2, otr_type))
930 invalid = true;
931 if (instance)
932 *instance = base_pointer;
933 return;
935 set_by_decl (base, offset + offset2);
936 if (outer_type && maybe_in_construction && stmt)
937 maybe_in_construction
938 = decl_maybe_in_construction_p (base,
939 outer_type,
940 stmt,
941 fndecl);
942 if (instance)
943 *instance = base;
944 return;
946 else
947 break;
949 else
950 break;
952 else if (TREE_CODE (base_pointer) == POINTER_PLUS_EXPR
953 && tree_fits_uhwi_p (TREE_OPERAND (base_pointer, 1)))
955 offset += tree_to_shwi (TREE_OPERAND (base_pointer, 1))
956 * BITS_PER_UNIT;
957 base_pointer = TREE_OPERAND (base_pointer, 0);
959 else
960 break;
963 if (visited)
964 delete (visited);
966 /* Try to determine type of the outer object. */
967 if (TREE_CODE (base_pointer) == SSA_NAME
968 && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
969 && TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL)
971 /* See if parameter is THIS pointer of a method. */
972 if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE
973 && SSA_NAME_VAR (base_pointer) == DECL_ARGUMENTS (fndecl))
975 outer_type
976 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
977 gcc_assert (TREE_CODE (outer_type) == RECORD_TYPE
978 || TREE_CODE (outer_type) == UNION_TYPE);
980 /* Dynamic casting has possibly upcasted the type
981 in the hiearchy. In this case outer type is less
982 informative than inner type and we should forget
983 about it. */
984 if ((otr_type
985 && !contains_type_p (outer_type, offset,
986 otr_type))
987 || !contains_polymorphic_type_p (outer_type))
989 outer_type = NULL;
990 if (instance)
991 *instance = base_pointer;
992 return;
995 dynamic = true;
997 /* If the function is constructor or destructor, then
998 the type is possibly in construction, but we know
999 it is not derived type. */
1000 if (DECL_CXX_CONSTRUCTOR_P (fndecl)
1001 || DECL_CXX_DESTRUCTOR_P (fndecl))
1003 maybe_in_construction = true;
1004 maybe_derived_type = false;
1006 else
1008 maybe_derived_type = true;
1009 maybe_in_construction = false;
1011 if (instance)
1012 *instance = base_pointer;
1013 return;
1015 /* Non-PODs passed by value are really passed by invisible
1016 reference. In this case we also know the type of the
1017 object. */
1018 if (DECL_BY_REFERENCE (SSA_NAME_VAR (base_pointer)))
1020 outer_type
1021 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
1022 /* Only type inconsistent programs can have otr_type that is
1023 not part of outer type. */
1024 if (otr_type && !contains_type_p (outer_type, offset,
1025 otr_type))
1027 invalid = true;
1028 if (instance)
1029 *instance = base_pointer;
1030 return;
1032 /* Non-polymorphic types have no interest for us. */
1033 else if (!otr_type && !contains_polymorphic_type_p (outer_type))
1035 outer_type = NULL;
1036 if (instance)
1037 *instance = base_pointer;
1038 return;
1040 maybe_derived_type = false;
1041 maybe_in_construction = false;
1042 if (instance)
1043 *instance = base_pointer;
1044 return;
1048 tree base_type = TREE_TYPE (base_pointer);
1050 if (TREE_CODE (base_pointer) == SSA_NAME
1051 && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
1052 && !(TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL
1053 || TREE_CODE (SSA_NAME_VAR (base_pointer)) == RESULT_DECL))
1055 invalid = true;
1056 if (instance)
1057 *instance = base_pointer;
1058 return;
1060 if (TREE_CODE (base_pointer) == SSA_NAME
1061 && SSA_NAME_DEF_STMT (base_pointer)
1062 && gimple_assign_single_p (SSA_NAME_DEF_STMT (base_pointer)))
1063 base_type = TREE_TYPE (gimple_assign_rhs1
1064 (SSA_NAME_DEF_STMT (base_pointer)));
1066 if (base_type && POINTER_TYPE_P (base_type))
1067 combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base_type)),
1068 offset,
1069 true, NULL /* Do not change type here */);
1070 /* TODO: There are multiple ways to derive a type. For instance
1071 if BASE_POINTER is passed to an constructor call prior our refernece.
1072 We do not make this type of flow sensitive analysis yet. */
1073 if (instance)
1074 *instance = base_pointer;
1075 return;
1078 /* Structure to be passed in between detect_type_change and
1079 check_stmt_for_type_change. */
1081 struct type_change_info
1083 /* Offset into the object where there is the virtual method pointer we are
1084 looking for. */
1085 HOST_WIDE_INT offset;
1086 /* The declaration or SSA_NAME pointer of the base that we are checking for
1087 type change. */
1088 tree instance;
1089 /* The reference to virtual table pointer used. */
1090 tree vtbl_ptr_ref;
1091 tree otr_type;
1092 /* If we actually can tell the type that the object has changed to, it is
1093 stored in this field. Otherwise it remains NULL_TREE. */
1094 tree known_current_type;
1095 HOST_WIDE_INT known_current_offset;
1097 /* Set to true if dynamic type change has been detected. */
1098 bool type_maybe_changed;
1099 /* Set to true if multiple types have been encountered. known_current_type
1100 must be disregarded in that case. */
1101 bool multiple_types_encountered;
1102 /* Set to true if we possibly missed some dynamic type changes and we should
1103 consider the set to be speculative. */
1104 bool speculative;
1105 bool seen_unanalyzed_store;
1108 /* Return true if STMT is not call and can modify a virtual method table pointer.
1109 We take advantage of fact that vtable stores must appear within constructor
1110 and destructor functions. */
1112 static bool
1113 noncall_stmt_may_be_vtbl_ptr_store (gimple *stmt)
1115 if (is_gimple_assign (stmt))
1117 tree lhs = gimple_assign_lhs (stmt);
1119 if (gimple_clobber_p (stmt))
1120 return false;
1121 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
1123 if (flag_strict_aliasing
1124 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
1125 return false;
1127 if (TREE_CODE (lhs) == COMPONENT_REF
1128 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
1129 return false;
1130 /* In the future we might want to use get_base_ref_and_offset to find
1131 if there is a field corresponding to the offset and if so, proceed
1132 almost like if it was a component ref. */
1136 /* Code unification may mess with inline stacks. */
1137 if (cfun->after_inlining)
1138 return true;
1140 /* Walk the inline stack and watch out for ctors/dtors.
1141 TODO: Maybe we can require the store to appear in toplevel
1142 block of CTOR/DTOR. */
1143 for (tree block = gimple_block (stmt); block && TREE_CODE (block) == BLOCK;
1144 block = BLOCK_SUPERCONTEXT (block))
1145 if (BLOCK_ABSTRACT_ORIGIN (block)
1146 && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) == FUNCTION_DECL)
1147 return inlined_polymorphic_ctor_dtor_block_p (block, false);
1148 return (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
1149 && (DECL_CXX_CONSTRUCTOR_P (current_function_decl)
1150 || DECL_CXX_DESTRUCTOR_P (current_function_decl)));
1153 /* If STMT can be proved to be an assignment to the virtual method table
1154 pointer of ANALYZED_OBJ and the type associated with the new table
1155 identified, return the type. Otherwise return NULL_TREE if type changes
1156 in unknown way or ERROR_MARK_NODE if type is unchanged. */
1158 static tree
1159 extr_type_from_vtbl_ptr_store (gimple *stmt, struct type_change_info *tci,
1160 HOST_WIDE_INT *type_offset)
1162 HOST_WIDE_INT offset, size, max_size;
1163 tree lhs, rhs, base;
1164 bool reverse;
1166 if (!gimple_assign_single_p (stmt))
1167 return NULL_TREE;
1169 lhs = gimple_assign_lhs (stmt);
1170 rhs = gimple_assign_rhs1 (stmt);
1171 if (TREE_CODE (lhs) != COMPONENT_REF
1172 || !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
1174 if (dump_file)
1175 fprintf (dump_file, " LHS is not virtual table.\n");
1176 return NULL_TREE;
1179 if (tci->vtbl_ptr_ref && operand_equal_p (lhs, tci->vtbl_ptr_ref, 0))
1181 else
1183 base = get_ref_base_and_extent (lhs, &offset, &size, &max_size, &reverse);
1184 if (DECL_P (tci->instance))
1186 if (base != tci->instance)
1188 if (dump_file)
1190 fprintf (dump_file, " base:");
1191 print_generic_expr (dump_file, base, TDF_SLIM);
1192 fprintf (dump_file, " does not match instance:");
1193 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1194 fprintf (dump_file, "\n");
1196 return NULL_TREE;
1199 else if (TREE_CODE (base) == MEM_REF)
1201 if (!operand_equal_p (tci->instance, TREE_OPERAND (base, 0), 0))
1203 if (dump_file)
1205 fprintf (dump_file, " base mem ref:");
1206 print_generic_expr (dump_file, base, TDF_SLIM);
1207 fprintf (dump_file, " does not match instance:");
1208 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1209 fprintf (dump_file, "\n");
1211 return NULL_TREE;
1213 if (!integer_zerop (TREE_OPERAND (base, 1)))
1215 if (!tree_fits_shwi_p (TREE_OPERAND (base, 1)))
1217 if (dump_file)
1219 fprintf (dump_file, " base mem ref:");
1220 print_generic_expr (dump_file, base, TDF_SLIM);
1221 fprintf (dump_file, " has non-representable offset:");
1222 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1223 fprintf (dump_file, "\n");
1225 return NULL_TREE;
1227 else
1228 offset += tree_to_shwi (TREE_OPERAND (base, 1)) * BITS_PER_UNIT;
1231 else if (!operand_equal_p (tci->instance, base, 0)
1232 || tci->offset)
1234 if (dump_file)
1236 fprintf (dump_file, " base:");
1237 print_generic_expr (dump_file, base, TDF_SLIM);
1238 fprintf (dump_file, " does not match instance:");
1239 print_generic_expr (dump_file, tci->instance, TDF_SLIM);
1240 fprintf (dump_file, " with offset %i\n", (int)tci->offset);
1242 return tci->offset > POINTER_SIZE ? error_mark_node : NULL_TREE;
1244 if (offset != tci->offset
1245 || size != POINTER_SIZE
1246 || max_size != POINTER_SIZE)
1248 if (dump_file)
1249 fprintf (dump_file, " wrong offset %i!=%i or size %i\n",
1250 (int)offset, (int)tci->offset, (int)size);
1251 return offset + POINTER_SIZE <= tci->offset
1252 || (max_size != -1
1253 && tci->offset + POINTER_SIZE > offset + max_size)
1254 ? error_mark_node : NULL;
1258 tree vtable;
1259 unsigned HOST_WIDE_INT offset2;
1261 if (!vtable_pointer_value_to_vtable (rhs, &vtable, &offset2))
1263 if (dump_file)
1264 fprintf (dump_file, " Failed to lookup binfo\n");
1265 return NULL;
1268 tree binfo = subbinfo_with_vtable_at_offset (TYPE_BINFO (DECL_CONTEXT (vtable)),
1269 offset2, vtable);
1270 if (!binfo)
1272 if (dump_file)
1273 fprintf (dump_file, " Construction vtable used\n");
1274 /* FIXME: We should suport construction contexts. */
1275 return NULL;
1278 *type_offset = tree_to_shwi (BINFO_OFFSET (binfo)) * BITS_PER_UNIT;
1279 return DECL_CONTEXT (vtable);
1282 /* Record dynamic type change of TCI to TYPE. */
1284 static void
1285 record_known_type (struct type_change_info *tci, tree type, HOST_WIDE_INT offset)
1287 if (dump_file)
1289 if (type)
1291 fprintf (dump_file, " Recording type: ");
1292 print_generic_expr (dump_file, type, TDF_SLIM);
1293 fprintf (dump_file, " at offset %i\n", (int)offset);
1295 else
1296 fprintf (dump_file, " Recording unknown type\n");
1299 /* If we found a constructor of type that is not polymorphic or
1300 that may contain the type in question as a field (not as base),
1301 restrict to the inner class first to make type matching bellow
1302 happier. */
1303 if (type
1304 && (offset
1305 || (TREE_CODE (type) != RECORD_TYPE
1306 || !TYPE_BINFO (type)
1307 || !polymorphic_type_binfo_p (TYPE_BINFO (type)))))
1309 ipa_polymorphic_call_context context;
1311 context.offset = offset;
1312 context.outer_type = type;
1313 context.maybe_in_construction = false;
1314 context.maybe_derived_type = false;
1315 context.dynamic = true;
1316 /* If we failed to find the inner type, we know that the call
1317 would be undefined for type produced here. */
1318 if (!context.restrict_to_inner_class (tci->otr_type))
1320 if (dump_file)
1321 fprintf (dump_file, " Ignoring; does not contain otr_type\n");
1322 return;
1324 /* Watch for case we reached an POD type and anticipate placement
1325 new. */
1326 if (!context.maybe_derived_type)
1328 type = context.outer_type;
1329 offset = context.offset;
1332 if (tci->type_maybe_changed
1333 && (!types_same_for_odr (type, tci->known_current_type)
1334 || offset != tci->known_current_offset))
1335 tci->multiple_types_encountered = true;
1336 tci->known_current_type = TYPE_MAIN_VARIANT (type);
1337 tci->known_current_offset = offset;
1338 tci->type_maybe_changed = true;
1341 /* Callback of walk_aliased_vdefs and a helper function for
1342 detect_type_change to check whether a particular statement may modify
1343 the virtual table pointer, and if possible also determine the new type of
1344 the (sub-)object. It stores its result into DATA, which points to a
1345 type_change_info structure. */
1347 static bool
1348 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
1350 gimple *stmt = SSA_NAME_DEF_STMT (vdef);
1351 struct type_change_info *tci = (struct type_change_info *) data;
1352 tree fn;
1354 /* If we already gave up, just terminate the rest of walk. */
1355 if (tci->multiple_types_encountered)
1356 return true;
1358 if (is_gimple_call (stmt))
1360 if (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))
1361 return false;
1363 /* Check for a constructor call. */
1364 if ((fn = gimple_call_fndecl (stmt)) != NULL_TREE
1365 && DECL_CXX_CONSTRUCTOR_P (fn)
1366 && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
1367 && gimple_call_num_args (stmt))
1369 tree op = walk_ssa_copies (gimple_call_arg (stmt, 0));
1370 tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
1371 HOST_WIDE_INT offset = 0, size, max_size;
1372 bool reverse;
1374 if (dump_file)
1376 fprintf (dump_file, " Checking constructor call: ");
1377 print_gimple_stmt (dump_file, stmt, 0, 0);
1380 /* See if THIS parameter seems like instance pointer. */
1381 if (TREE_CODE (op) == ADDR_EXPR)
1383 op = get_ref_base_and_extent (TREE_OPERAND (op, 0), &offset,
1384 &size, &max_size, &reverse);
1385 if (size != max_size || max_size == -1)
1387 tci->speculative = true;
1388 return false;
1390 if (op && TREE_CODE (op) == MEM_REF)
1392 if (!tree_fits_shwi_p (TREE_OPERAND (op, 1)))
1394 tci->speculative = true;
1395 return false;
1397 offset += tree_to_shwi (TREE_OPERAND (op, 1))
1398 * BITS_PER_UNIT;
1399 op = TREE_OPERAND (op, 0);
1401 else if (DECL_P (op))
1403 else
1405 tci->speculative = true;
1406 return false;
1408 op = walk_ssa_copies (op);
1410 if (operand_equal_p (op, tci->instance, 0)
1411 && TYPE_SIZE (type)
1412 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
1413 && tree_fits_shwi_p (TYPE_SIZE (type))
1414 && tree_to_shwi (TYPE_SIZE (type)) + offset > tci->offset
1415 /* Some inlined constructors may look as follows:
1416 _3 = operator new (16);
1417 MEM[(struct &)_3] ={v} {CLOBBER};
1418 MEM[(struct CompositeClass *)_3]._vptr.CompositeClass
1419 = &MEM[(void *)&_ZTV14CompositeClass + 16B];
1420 _7 = &MEM[(struct CompositeClass *)_3].object;
1421 EmptyClass::EmptyClass (_7);
1423 When determining dynamic type of _3 and because we stop at first
1424 dynamic type found, we would stop on EmptyClass::EmptyClass (_7).
1425 In this case the emptyclass is not even polymorphic and we miss
1426 it is contained in an outer type that is polymorphic. */
1428 && (tci->offset == offset || contains_polymorphic_type_p (type)))
1430 record_known_type (tci, type, tci->offset - offset);
1431 return true;
1434 /* Calls may possibly change dynamic type by placement new. Assume
1435 it will not happen, but make result speculative only. */
1436 if (dump_file)
1438 fprintf (dump_file, " Function call may change dynamic type:");
1439 print_gimple_stmt (dump_file, stmt, 0, 0);
1441 tci->speculative = true;
1442 return false;
1444 /* Check for inlined virtual table store. */
1445 else if (noncall_stmt_may_be_vtbl_ptr_store (stmt))
1447 tree type;
1448 HOST_WIDE_INT offset = 0;
1449 if (dump_file)
1451 fprintf (dump_file, " Checking vtbl store: ");
1452 print_gimple_stmt (dump_file, stmt, 0, 0);
1455 type = extr_type_from_vtbl_ptr_store (stmt, tci, &offset);
1456 if (type == error_mark_node)
1457 return false;
1458 gcc_assert (!type || TYPE_MAIN_VARIANT (type) == type);
1459 if (!type)
1461 if (dump_file)
1462 fprintf (dump_file, " Unanalyzed store may change type.\n");
1463 tci->seen_unanalyzed_store = true;
1464 tci->speculative = true;
1466 else
1467 record_known_type (tci, type, offset);
1468 return true;
1470 else
1471 return false;
1474 /* THIS is polymorphic call context obtained from get_polymorphic_context.
1475 OTR_OBJECT is pointer to the instance returned by OBJ_TYPE_REF_OBJECT.
1476 INSTANCE is pointer to the outer instance as returned by
1477 get_polymorphic_context. To avoid creation of temporary expressions,
1478 INSTANCE may also be an declaration of get_polymorphic_context found the
1479 value to be in static storage.
1481 If the type of instance is not fully determined
1482 (either OUTER_TYPE is unknown or MAYBE_IN_CONSTRUCTION/INCLUDE_DERIVED_TYPES
1483 is set), try to walk memory writes and find the actual construction of the
1484 instance.
1486 Return true if memory is unchanged from function entry.
1488 We do not include this analysis in the context analysis itself, because
1489 it needs memory SSA to be fully built and the walk may be expensive.
1490 So it is not suitable for use withing fold_stmt and similar uses. */
1492 bool
1493 ipa_polymorphic_call_context::get_dynamic_type (tree instance,
1494 tree otr_object,
1495 tree otr_type,
1496 gimple *call)
1498 struct type_change_info tci;
1499 ao_ref ao;
1500 bool function_entry_reached = false;
1501 tree instance_ref = NULL;
1502 gimple *stmt = call;
1503 /* Remember OFFSET before it is modified by restrict_to_inner_class.
1504 This is because we do not update INSTANCE when walking inwards. */
1505 HOST_WIDE_INT instance_offset = offset;
1506 tree instance_outer_type = outer_type;
1508 if (otr_type)
1509 otr_type = TYPE_MAIN_VARIANT (otr_type);
1511 /* Walk into inner type. This may clear maybe_derived_type and save us
1512 from useless work. It also makes later comparsions with static type
1513 easier. */
1514 if (outer_type && otr_type)
1516 if (!restrict_to_inner_class (otr_type))
1517 return false;
1520 if (!maybe_in_construction && !maybe_derived_type)
1521 return false;
1523 /* We need to obtain refernce to virtual table pointer. It is better
1524 to look it up in the code rather than build our own. This require bit
1525 of pattern matching, but we end up verifying that what we found is
1526 correct.
1528 What we pattern match is:
1530 tmp = instance->_vptr.A; // vtbl ptr load
1531 tmp2 = tmp[otr_token]; // vtable lookup
1532 OBJ_TYPE_REF(tmp2;instance->0) (instance);
1534 We want to start alias oracle walk from vtbl pointer load,
1535 but we may not be able to identify it, for example, when PRE moved the
1536 load around. */
1538 if (gimple_code (call) == GIMPLE_CALL)
1540 tree ref = gimple_call_fn (call);
1541 HOST_WIDE_INT offset2, size, max_size;
1542 bool reverse;
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
1573 = get_ref_base_and_extent (ref_exp, &offset2, &size,
1574 &max_size, &reverse);
1576 /* Finally verify that what we found looks like read from
1577 OTR_OBJECT or from INSTANCE with offset OFFSET. */
1578 if (base_ref
1579 && ((TREE_CODE (base_ref) == MEM_REF
1580 && ((offset2 == instance_offset
1581 && TREE_OPERAND (base_ref, 0) == instance)
1582 || (!offset2
1583 && TREE_OPERAND (base_ref, 0)
1584 == otr_object)))
1585 || (DECL_P (instance) && base_ref == instance
1586 && offset2 == instance_offset)))
1588 stmt = SSA_NAME_DEF_STMT (ref);
1589 instance_ref = ref_exp;
1596 /* If we failed to look up the reference in code, build our own. */
1597 if (!instance_ref)
1599 /* If the statement in question does not use memory, we can't tell
1600 anything. */
1601 if (!gimple_vuse (stmt))
1602 return false;
1603 ao_ref_init_from_ptr_and_size (&ao, otr_object, NULL);
1605 else
1606 /* Otherwise use the real reference. */
1607 ao_ref_init (&ao, instance_ref);
1609 /* We look for vtbl pointer read. */
1610 ao.size = POINTER_SIZE;
1611 ao.max_size = ao.size;
1612 /* We are looking for stores to vptr pointer within the instance of
1613 outer type.
1614 TODO: The vptr pointer type is globally known, we probably should
1615 keep it and do that even when otr_type is unknown. */
1616 if (otr_type)
1618 ao.base_alias_set
1619 = get_alias_set (outer_type ? outer_type : otr_type);
1620 ao.ref_alias_set
1621 = get_alias_set (TREE_TYPE (BINFO_VTABLE (TYPE_BINFO (otr_type))));
1624 if (dump_file)
1626 fprintf (dump_file, "Determining dynamic type for call: ");
1627 print_gimple_stmt (dump_file, call, 0, 0);
1628 fprintf (dump_file, " Starting walk at: ");
1629 print_gimple_stmt (dump_file, stmt, 0, 0);
1630 fprintf (dump_file, " instance pointer: ");
1631 print_generic_expr (dump_file, otr_object, TDF_SLIM);
1632 fprintf (dump_file, " Outer instance pointer: ");
1633 print_generic_expr (dump_file, instance, TDF_SLIM);
1634 fprintf (dump_file, " offset: %i (bits)", (int)instance_offset);
1635 fprintf (dump_file, " vtbl reference: ");
1636 print_generic_expr (dump_file, instance_ref, TDF_SLIM);
1637 fprintf (dump_file, "\n");
1640 tci.offset = instance_offset;
1641 tci.instance = instance;
1642 tci.vtbl_ptr_ref = instance_ref;
1643 gcc_assert (TREE_CODE (instance) != MEM_REF);
1644 tci.known_current_type = NULL_TREE;
1645 tci.known_current_offset = 0;
1646 tci.otr_type = otr_type;
1647 tci.type_maybe_changed = false;
1648 tci.multiple_types_encountered = false;
1649 tci.speculative = false;
1650 tci.seen_unanalyzed_store = false;
1652 walk_aliased_vdefs (&ao, gimple_vuse (stmt), check_stmt_for_type_change,
1653 &tci, NULL, &function_entry_reached);
1655 /* If we did not find any type changing statements, we may still drop
1656 maybe_in_construction flag if the context already have outer type.
1658 Here we make special assumptions about both constructors and
1659 destructors which are all the functions that are allowed to alter the
1660 VMT pointers. It assumes that destructors begin with assignment into
1661 all VMT pointers and that constructors essentially look in the
1662 following way:
1664 1) The very first thing they do is that they call constructors of
1665 ancestor sub-objects that have them.
1667 2) Then VMT pointers of this and all its ancestors is set to new
1668 values corresponding to the type corresponding to the constructor.
1670 3) Only afterwards, other stuff such as constructor of member
1671 sub-objects and the code written by the user is run. Only this may
1672 include calling virtual functions, directly or indirectly.
1674 4) placement new can not be used to change type of non-POD statically
1675 allocated variables.
1677 There is no way to call a constructor of an ancestor sub-object in any
1678 other way.
1680 This means that we do not have to care whether constructors get the
1681 correct type information because they will always change it (in fact,
1682 if we define the type to be given by the VMT pointer, it is undefined).
1684 The most important fact to derive from the above is that if, for some
1685 statement in the section 3, we try to detect whether the dynamic type
1686 has changed, we can safely ignore all calls as we examine the function
1687 body backwards until we reach statements in section 2 because these
1688 calls cannot be ancestor constructors or destructors (if the input is
1689 not bogus) and so do not change the dynamic type (this holds true only
1690 for automatically allocated objects but at the moment we devirtualize
1691 only these). We then must detect that statements in section 2 change
1692 the dynamic type and can try to derive the new type. That is enough
1693 and we can stop, we will never see the calls into constructors of
1694 sub-objects in this code.
1696 Therefore if the static outer type was found (outer_type)
1697 we can safely ignore tci.speculative that is set on calls and give up
1698 only if there was dyanmic type store that may affect given variable
1699 (seen_unanalyzed_store) */
1701 if (!tci.type_maybe_changed
1702 || (outer_type
1703 && !dynamic
1704 && !tci.seen_unanalyzed_store
1705 && !tci.multiple_types_encountered
1706 && ((offset == tci.offset
1707 && types_same_for_odr (tci.known_current_type,
1708 outer_type))
1709 || (instance_offset == offset
1710 && types_same_for_odr (tci.known_current_type,
1711 instance_outer_type)))))
1713 if (!outer_type || tci.seen_unanalyzed_store)
1714 return false;
1715 if (maybe_in_construction)
1716 maybe_in_construction = false;
1717 if (dump_file)
1718 fprintf (dump_file, " No dynamic type change found.\n");
1719 return true;
1722 if (tci.known_current_type
1723 && !function_entry_reached
1724 && !tci.multiple_types_encountered)
1726 if (!tci.speculative)
1728 outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
1729 offset = tci.known_current_offset;
1730 dynamic = true;
1731 maybe_in_construction = false;
1732 maybe_derived_type = false;
1733 if (dump_file)
1734 fprintf (dump_file, " Determined dynamic type.\n");
1736 else if (!speculative_outer_type
1737 || speculative_maybe_derived_type)
1739 speculative_outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
1740 speculative_offset = tci.known_current_offset;
1741 speculative_maybe_derived_type = false;
1742 if (dump_file)
1743 fprintf (dump_file, " Determined speculative dynamic type.\n");
1746 else if (dump_file)
1748 fprintf (dump_file, " Found multiple types%s%s\n",
1749 function_entry_reached ? " (function entry reached)" : "",
1750 function_entry_reached ? " (multiple types encountered)" : "");
1753 return false;
1756 /* See if speculation given by SPEC_OUTER_TYPE, SPEC_OFFSET and SPEC_MAYBE_DERIVED_TYPE
1757 seems consistent (and useful) with what we already have in the non-speculative context. */
1759 bool
1760 ipa_polymorphic_call_context::speculation_consistent_p (tree spec_outer_type,
1761 HOST_WIDE_INT spec_offset,
1762 bool spec_maybe_derived_type,
1763 tree otr_type) const
1765 if (!flag_devirtualize_speculatively)
1766 return false;
1768 /* Non-polymorphic types are useless for deriving likely polymorphic
1769 call targets. */
1770 if (!spec_outer_type || !contains_polymorphic_type_p (spec_outer_type))
1771 return false;
1773 /* If we know nothing, speculation is always good. */
1774 if (!outer_type)
1775 return true;
1777 /* Speculation is only useful to avoid derived types.
1778 This is not 100% true for placement new, where the outer context may
1779 turn out to be useless, but ignore these for now. */
1780 if (!maybe_derived_type)
1781 return false;
1783 /* If types agrees, speculation is consistent, but it makes sense only
1784 when it says something new. */
1785 if (types_must_be_same_for_odr (spec_outer_type, outer_type))
1786 return maybe_derived_type && !spec_maybe_derived_type;
1788 /* If speculation does not contain the type in question, ignore it. */
1789 if (otr_type
1790 && !contains_type_p (spec_outer_type, spec_offset, otr_type, false, true))
1791 return false;
1793 /* If outer type already contains speculation as a filed,
1794 it is useless. We already know from OUTER_TYPE
1795 SPEC_TYPE and that it is not in the construction. */
1796 if (contains_type_p (outer_type, offset - spec_offset,
1797 spec_outer_type, false, false))
1798 return false;
1800 /* If speculative outer type is not more specified than outer
1801 type, just give up.
1802 We can only decide this safely if we can compare types with OUTER_TYPE.
1804 if ((!in_lto_p || odr_type_p (outer_type))
1805 && !contains_type_p (spec_outer_type,
1806 spec_offset - offset,
1807 outer_type, false))
1808 return false;
1809 return true;
1812 /* Improve THIS with speculation described by NEW_OUTER_TYPE, NEW_OFFSET,
1813 NEW_MAYBE_DERIVED_TYPE
1814 If OTR_TYPE is set, assume the context is used with OTR_TYPE. */
1816 bool
1817 ipa_polymorphic_call_context::combine_speculation_with
1818 (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
1819 tree otr_type)
1821 if (!new_outer_type)
1822 return false;
1824 /* restrict_to_inner_class may eliminate wrong speculation making our job
1825 easeier. */
1826 if (otr_type)
1827 restrict_to_inner_class (otr_type);
1829 if (!speculation_consistent_p (new_outer_type, new_offset,
1830 new_maybe_derived_type, otr_type))
1831 return false;
1833 /* New speculation is a win in case we have no speculation or new
1834 speculation does not consider derivations. */
1835 if (!speculative_outer_type
1836 || (speculative_maybe_derived_type
1837 && !new_maybe_derived_type))
1839 speculative_outer_type = new_outer_type;
1840 speculative_offset = new_offset;
1841 speculative_maybe_derived_type = new_maybe_derived_type;
1842 return true;
1844 else if (types_must_be_same_for_odr (speculative_outer_type,
1845 new_outer_type))
1847 if (speculative_offset != new_offset)
1849 /* OK we have two contexts that seems valid but they disagree,
1850 just give up.
1852 This is not a lattice operation, so we may want to drop it later. */
1853 if (dump_file && (dump_flags & TDF_DETAILS))
1854 fprintf (dump_file,
1855 "Speculative outer types match, "
1856 "offset mismatch -> invalid speculation\n");
1857 clear_speculation ();
1858 return true;
1860 else
1862 if (speculative_maybe_derived_type && !new_maybe_derived_type)
1864 speculative_maybe_derived_type = false;
1865 return true;
1867 else
1868 return false;
1871 /* Choose type that contains the other. This one either contains the outer
1872 as a field (thus giving exactly one target) or is deeper in the type
1873 hiearchy. */
1874 else if (speculative_outer_type
1875 && speculative_maybe_derived_type
1876 && (new_offset > speculative_offset
1877 || (new_offset == speculative_offset
1878 && contains_type_p (new_outer_type,
1879 0, speculative_outer_type, false))))
1881 tree old_outer_type = speculative_outer_type;
1882 HOST_WIDE_INT old_offset = speculative_offset;
1883 bool old_maybe_derived_type = speculative_maybe_derived_type;
1885 speculative_outer_type = new_outer_type;
1886 speculative_offset = new_offset;
1887 speculative_maybe_derived_type = new_maybe_derived_type;
1889 if (otr_type)
1890 restrict_to_inner_class (otr_type);
1892 /* If the speculation turned out to make no sense, revert to sensible
1893 one. */
1894 if (!speculative_outer_type)
1896 speculative_outer_type = old_outer_type;
1897 speculative_offset = old_offset;
1898 speculative_maybe_derived_type = old_maybe_derived_type;
1899 return false;
1901 return (old_offset != speculative_offset
1902 || old_maybe_derived_type != speculative_maybe_derived_type
1903 || types_must_be_same_for_odr (speculative_outer_type,
1904 new_outer_type));
1906 return false;
1909 /* Make speculation less specific so
1910 NEW_OUTER_TYPE, NEW_OFFSET, NEW_MAYBE_DERIVED_TYPE is also included.
1911 If OTR_TYPE is set, assume the context is used with OTR_TYPE. */
1913 bool
1914 ipa_polymorphic_call_context::meet_speculation_with
1915 (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
1916 tree otr_type)
1918 if (!new_outer_type && speculative_outer_type)
1920 clear_speculation ();
1921 return true;
1924 /* restrict_to_inner_class may eliminate wrong speculation making our job
1925 easeier. */
1926 if (otr_type)
1927 restrict_to_inner_class (otr_type);
1929 if (!speculative_outer_type
1930 || !speculation_consistent_p (speculative_outer_type,
1931 speculative_offset,
1932 speculative_maybe_derived_type,
1933 otr_type))
1934 return false;
1936 if (!speculation_consistent_p (new_outer_type, new_offset,
1937 new_maybe_derived_type, otr_type))
1939 clear_speculation ();
1940 return true;
1943 else if (types_must_be_same_for_odr (speculative_outer_type,
1944 new_outer_type))
1946 if (speculative_offset != new_offset)
1948 clear_speculation ();
1949 return true;
1951 else
1953 if (!speculative_maybe_derived_type && new_maybe_derived_type)
1955 speculative_maybe_derived_type = true;
1956 return true;
1958 else
1959 return false;
1962 /* See if one type contains the other as a field (not base). */
1963 else if (contains_type_p (new_outer_type, new_offset - speculative_offset,
1964 speculative_outer_type, false, false))
1965 return false;
1966 else if (contains_type_p (speculative_outer_type,
1967 speculative_offset - new_offset,
1968 new_outer_type, false, false))
1970 speculative_outer_type = new_outer_type;
1971 speculative_offset = new_offset;
1972 speculative_maybe_derived_type = new_maybe_derived_type;
1973 return true;
1975 /* See if OUTER_TYPE is base of CTX.OUTER_TYPE. */
1976 else if (contains_type_p (new_outer_type,
1977 new_offset - speculative_offset,
1978 speculative_outer_type, false, true))
1980 if (!speculative_maybe_derived_type)
1982 speculative_maybe_derived_type = true;
1983 return true;
1985 return false;
1987 /* See if CTX.OUTER_TYPE is base of OUTER_TYPE. */
1988 else if (contains_type_p (speculative_outer_type,
1989 speculative_offset - new_offset, new_outer_type, false, true))
1991 speculative_outer_type = new_outer_type;
1992 speculative_offset = new_offset;
1993 speculative_maybe_derived_type = true;
1994 return true;
1996 else
1998 if (dump_file && (dump_flags & TDF_DETAILS))
1999 fprintf (dump_file, "Giving up on speculative meet\n");
2000 clear_speculation ();
2001 return true;
2005 /* Assume that both THIS and a given context is valid and strenghten THIS
2006 if possible. Return true if any strenghtening was made.
2007 If actual type the context is being used in is known, OTR_TYPE should be
2008 set accordingly. This improves quality of combined result. */
2010 bool
2011 ipa_polymorphic_call_context::combine_with (ipa_polymorphic_call_context ctx,
2012 tree otr_type)
2014 bool updated = false;
2016 if (ctx.useless_p () || invalid)
2017 return false;
2019 /* Restricting context to inner type makes merging easier, however do not
2020 do that unless we know how the context is used (OTR_TYPE is non-NULL) */
2021 if (otr_type && !invalid && !ctx.invalid)
2023 restrict_to_inner_class (otr_type);
2024 ctx.restrict_to_inner_class (otr_type);
2025 if(invalid)
2026 return false;
2029 if (dump_file && (dump_flags & TDF_DETAILS))
2031 fprintf (dump_file, "Polymorphic call context combine:");
2032 dump (dump_file);
2033 fprintf (dump_file, "With context: ");
2034 ctx.dump (dump_file);
2035 if (otr_type)
2037 fprintf (dump_file, "To be used with type: ");
2038 print_generic_expr (dump_file, otr_type, TDF_SLIM);
2039 fprintf (dump_file, "\n");
2043 /* If call is known to be invalid, we are done. */
2044 if (ctx.invalid)
2046 if (dump_file && (dump_flags & TDF_DETAILS))
2047 fprintf (dump_file, "-> Invalid context\n");
2048 goto invalidate;
2051 if (!ctx.outer_type)
2053 else if (!outer_type)
2055 outer_type = ctx.outer_type;
2056 offset = ctx.offset;
2057 dynamic = ctx.dynamic;
2058 maybe_in_construction = ctx.maybe_in_construction;
2059 maybe_derived_type = ctx.maybe_derived_type;
2060 updated = true;
2062 /* If types are known to be same, merging is quite easy. */
2063 else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
2065 if (offset != ctx.offset
2066 && TYPE_SIZE (outer_type)
2067 && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
2069 if (dump_file && (dump_flags & TDF_DETAILS))
2070 fprintf (dump_file, "Outer types match, offset mismatch -> invalid\n");
2071 clear_speculation ();
2072 clear_outer_type ();
2073 invalid = true;
2074 return true;
2076 if (dump_file && (dump_flags & TDF_DETAILS))
2077 fprintf (dump_file, "Outer types match, merging flags\n");
2078 if (maybe_in_construction && !ctx.maybe_in_construction)
2080 updated = true;
2081 maybe_in_construction = false;
2083 if (maybe_derived_type && !ctx.maybe_derived_type)
2085 updated = true;
2086 maybe_derived_type = false;
2088 if (dynamic && !ctx.dynamic)
2090 updated = true;
2091 dynamic = false;
2094 /* If we know the type precisely, there is not much to improve. */
2095 else if (!maybe_derived_type && !maybe_in_construction
2096 && !ctx.maybe_derived_type && !ctx.maybe_in_construction)
2098 /* It may be easy to check if second context permits the first
2099 and set INVALID otherwise. This is not easy to do in general;
2100 contains_type_p may return false negatives for non-comparable
2101 types.
2103 If OTR_TYPE is known, we however can expect that
2104 restrict_to_inner_class should have discovered the same base
2105 type. */
2106 if (otr_type && !ctx.maybe_in_construction && !ctx.maybe_derived_type)
2108 if (dump_file && (dump_flags & TDF_DETAILS))
2109 fprintf (dump_file, "Contextes disagree -> invalid\n");
2110 goto invalidate;
2113 /* See if one type contains the other as a field (not base).
2114 In this case we want to choose the wider type, because it contains
2115 more information. */
2116 else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
2117 outer_type, false, false))
2119 if (dump_file && (dump_flags & TDF_DETAILS))
2120 fprintf (dump_file, "Second type contain the first as a field\n");
2122 if (maybe_derived_type)
2124 outer_type = ctx.outer_type;
2125 maybe_derived_type = ctx.maybe_derived_type;
2126 offset = ctx.offset;
2127 dynamic = ctx.dynamic;
2128 updated = true;
2131 /* If we do not know how the context is being used, we can
2132 not clear MAYBE_IN_CONSTRUCTION because it may be offseted
2133 to other component of OUTER_TYPE later and we know nothing
2134 about it. */
2135 if (otr_type && maybe_in_construction
2136 && !ctx.maybe_in_construction)
2138 maybe_in_construction = false;
2139 updated = true;
2142 else if (contains_type_p (outer_type, offset - ctx.offset,
2143 ctx.outer_type, false, false))
2145 if (dump_file && (dump_flags & TDF_DETAILS))
2146 fprintf (dump_file, "First type contain the second as a field\n");
2148 if (otr_type && maybe_in_construction
2149 && !ctx.maybe_in_construction)
2151 maybe_in_construction = false;
2152 updated = true;
2155 /* See if OUTER_TYPE is base of CTX.OUTER_TYPE. */
2156 else if (contains_type_p (ctx.outer_type,
2157 ctx.offset - offset, outer_type, false, true))
2159 if (dump_file && (dump_flags & TDF_DETAILS))
2160 fprintf (dump_file, "First type is base of second\n");
2161 if (!maybe_derived_type)
2163 if (!ctx.maybe_in_construction
2164 && types_odr_comparable (outer_type, ctx.outer_type))
2166 if (dump_file && (dump_flags & TDF_DETAILS))
2167 fprintf (dump_file, "Second context does not permit base -> invalid\n");
2168 goto invalidate;
2171 /* Pick variant deeper in the hiearchy. */
2172 else
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;
2182 /* See if CTX.OUTER_TYPE is base of OUTER_TYPE. */
2183 else if (contains_type_p (outer_type,
2184 offset - ctx.offset, ctx.outer_type, false, true))
2186 if (dump_file && (dump_flags & TDF_DETAILS))
2187 fprintf (dump_file, "Second type is base of first\n");
2188 if (!ctx.maybe_derived_type)
2190 if (!maybe_in_construction
2191 && types_odr_comparable (outer_type, ctx.outer_type))
2193 if (dump_file && (dump_flags & TDF_DETAILS))
2194 fprintf (dump_file, "First context does not permit base -> invalid\n");
2195 goto invalidate;
2197 /* Pick the base type. */
2198 else if (maybe_in_construction)
2200 outer_type = ctx.outer_type;
2201 maybe_in_construction = ctx.maybe_in_construction;
2202 maybe_derived_type = ctx.maybe_derived_type;
2203 offset = ctx.offset;
2204 dynamic = ctx.dynamic;
2205 updated = true;
2209 /* TODO handle merging using hiearchy. */
2210 else if (dump_file && (dump_flags & TDF_DETAILS))
2211 fprintf (dump_file, "Giving up on merge\n");
2213 updated |= combine_speculation_with (ctx.speculative_outer_type,
2214 ctx.speculative_offset,
2215 ctx.speculative_maybe_derived_type,
2216 otr_type);
2218 if (updated && dump_file && (dump_flags & TDF_DETAILS))
2220 fprintf (dump_file, "Updated as: ");
2221 dump (dump_file);
2222 fprintf (dump_file, "\n");
2224 return updated;
2226 invalidate:
2227 invalid = true;
2228 clear_speculation ();
2229 clear_outer_type ();
2230 return true;
2233 /* Take non-speculative info, merge it with speculative and clear speculation.
2234 Used when we no longer manage to keep track of actual outer type, but we
2235 think it is still there.
2237 If OTR_TYPE is set, the transformation can be done more effectively assuming
2238 that context is going to be used only that way. */
2240 void
2241 ipa_polymorphic_call_context::make_speculative (tree otr_type)
2243 tree spec_outer_type = outer_type;
2244 HOST_WIDE_INT spec_offset = offset;
2245 bool spec_maybe_derived_type = maybe_derived_type;
2247 if (invalid)
2249 invalid = false;
2250 clear_outer_type ();
2251 clear_speculation ();
2252 return;
2254 if (!outer_type)
2255 return;
2256 clear_outer_type ();
2257 combine_speculation_with (spec_outer_type, spec_offset,
2258 spec_maybe_derived_type,
2259 otr_type);
2262 /* Use when we can not track dynamic type change. This speculatively assume
2263 type change is not happening. */
2265 void
2266 ipa_polymorphic_call_context::possible_dynamic_type_change (bool in_poly_cdtor,
2267 tree otr_type)
2269 if (dynamic)
2270 make_speculative (otr_type);
2271 else if (in_poly_cdtor)
2272 maybe_in_construction = true;
2275 /* Return TRUE if this context conveys the same information as OTHER. */
2277 bool
2278 ipa_polymorphic_call_context::equal_to
2279 (const ipa_polymorphic_call_context &x) const
2281 if (useless_p ())
2282 return x.useless_p ();
2283 if (invalid)
2284 return x.invalid;
2285 if (x.useless_p () || x.invalid)
2286 return false;
2288 if (outer_type)
2290 if (!x.outer_type
2291 || !types_odr_comparable (outer_type, x.outer_type)
2292 || !types_same_for_odr (outer_type, x.outer_type)
2293 || offset != x.offset
2294 || maybe_in_construction != x.maybe_in_construction
2295 || maybe_derived_type != x.maybe_derived_type
2296 || dynamic != x.dynamic)
2297 return false;
2299 else if (x.outer_type)
2300 return false;
2303 if (speculative_outer_type
2304 && speculation_consistent_p (speculative_outer_type, speculative_offset,
2305 speculative_maybe_derived_type, NULL_TREE))
2307 if (!x.speculative_outer_type)
2308 return false;
2310 if (!types_odr_comparable (speculative_outer_type,
2311 x.speculative_outer_type)
2312 || !types_same_for_odr (speculative_outer_type,
2313 x.speculative_outer_type)
2314 || speculative_offset != x.speculative_offset
2315 || speculative_maybe_derived_type != x.speculative_maybe_derived_type)
2316 return false;
2318 else if (x.speculative_outer_type
2319 && x.speculation_consistent_p (x.speculative_outer_type,
2320 x.speculative_offset,
2321 x.speculative_maybe_derived_type,
2322 NULL))
2323 return false;
2325 return true;
2328 /* Modify context to be strictly less restrictive than CTX. */
2330 bool
2331 ipa_polymorphic_call_context::meet_with (ipa_polymorphic_call_context ctx,
2332 tree otr_type)
2334 bool updated = false;
2336 if (useless_p () || ctx.invalid)
2337 return false;
2339 /* Restricting context to inner type makes merging easier, however do not
2340 do that unless we know how the context is used (OTR_TYPE is non-NULL) */
2341 if (otr_type && !useless_p () && !ctx.useless_p ())
2343 restrict_to_inner_class (otr_type);
2344 ctx.restrict_to_inner_class (otr_type);
2345 if(invalid)
2346 return false;
2349 if (equal_to (ctx))
2350 return false;
2352 if (ctx.useless_p () || invalid)
2354 *this = ctx;
2355 return true;
2358 if (dump_file && (dump_flags & TDF_DETAILS))
2360 fprintf (dump_file, "Polymorphic call context meet:");
2361 dump (dump_file);
2362 fprintf (dump_file, "With context: ");
2363 ctx.dump (dump_file);
2364 if (otr_type)
2366 fprintf (dump_file, "To be used with type: ");
2367 print_generic_expr (dump_file, otr_type, TDF_SLIM);
2368 fprintf (dump_file, "\n");
2372 if (!dynamic && ctx.dynamic)
2374 dynamic = true;
2375 updated = true;
2378 /* If call is known to be invalid, we are done. */
2379 if (!outer_type)
2381 else if (!ctx.outer_type)
2383 clear_outer_type ();
2384 updated = true;
2386 /* If types are known to be same, merging is quite easy. */
2387 else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
2389 if (offset != ctx.offset
2390 && TYPE_SIZE (outer_type)
2391 && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
2393 if (dump_file && (dump_flags & TDF_DETAILS))
2394 fprintf (dump_file, "Outer types match, offset mismatch -> clearing\n");
2395 clear_outer_type ();
2396 return true;
2398 if (dump_file && (dump_flags & TDF_DETAILS))
2399 fprintf (dump_file, "Outer types match, merging flags\n");
2400 if (!maybe_in_construction && ctx.maybe_in_construction)
2402 updated = true;
2403 maybe_in_construction = true;
2405 if (!maybe_derived_type && ctx.maybe_derived_type)
2407 updated = true;
2408 maybe_derived_type = true;
2410 if (!dynamic && ctx.dynamic)
2412 updated = true;
2413 dynamic = true;
2416 /* See if one type contains the other as a field (not base). */
2417 else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
2418 outer_type, false, false))
2420 if (dump_file && (dump_flags & TDF_DETAILS))
2421 fprintf (dump_file, "Second type contain the first as a field\n");
2423 /* The second type is more specified, so we keep the first.
2424 We need to set DYNAMIC flag to avoid declaring context INVALID
2425 of OFFSET ends up being out of range. */
2426 if (!dynamic
2427 && (ctx.dynamic
2428 || (!otr_type
2429 && (!TYPE_SIZE (ctx.outer_type)
2430 || !TYPE_SIZE (outer_type)
2431 || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
2432 TYPE_SIZE (outer_type), 0)))))
2434 dynamic = true;
2435 updated = true;
2438 else if (contains_type_p (outer_type, offset - ctx.offset,
2439 ctx.outer_type, false, false))
2441 if (dump_file && (dump_flags & TDF_DETAILS))
2442 fprintf (dump_file, "First type contain the second as a field\n");
2444 if (!dynamic
2445 && (ctx.dynamic
2446 || (!otr_type
2447 && (!TYPE_SIZE (ctx.outer_type)
2448 || !TYPE_SIZE (outer_type)
2449 || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
2450 TYPE_SIZE (outer_type), 0)))))
2451 dynamic = true;
2452 outer_type = ctx.outer_type;
2453 offset = ctx.offset;
2454 dynamic = ctx.dynamic;
2455 maybe_in_construction = ctx.maybe_in_construction;
2456 maybe_derived_type = ctx.maybe_derived_type;
2457 updated = true;
2459 /* See if OUTER_TYPE is base of CTX.OUTER_TYPE. */
2460 else if (contains_type_p (ctx.outer_type,
2461 ctx.offset - offset, outer_type, false, true))
2463 if (dump_file && (dump_flags & TDF_DETAILS))
2464 fprintf (dump_file, "First type is base of second\n");
2465 if (!maybe_derived_type)
2467 maybe_derived_type = true;
2468 updated = true;
2470 if (!maybe_in_construction && ctx.maybe_in_construction)
2472 maybe_in_construction = true;
2473 updated = true;
2475 if (!dynamic && ctx.dynamic)
2477 dynamic = true;
2478 updated = true;
2481 /* See if CTX.OUTER_TYPE is base of OUTER_TYPE. */
2482 else if (contains_type_p (outer_type,
2483 offset - ctx.offset, ctx.outer_type, false, true))
2485 if (dump_file && (dump_flags & TDF_DETAILS))
2486 fprintf (dump_file, "Second type is base of first\n");
2487 outer_type = ctx.outer_type;
2488 offset = ctx.offset;
2489 updated = true;
2490 if (!maybe_derived_type)
2491 maybe_derived_type = true;
2492 if (!maybe_in_construction && ctx.maybe_in_construction)
2493 maybe_in_construction = true;
2494 if (!dynamic && ctx.dynamic)
2495 dynamic = true;
2497 /* TODO handle merging using hiearchy. */
2498 else
2500 if (dump_file && (dump_flags & TDF_DETAILS))
2501 fprintf (dump_file, "Giving up on meet\n");
2502 clear_outer_type ();
2503 updated = true;
2506 updated |= meet_speculation_with (ctx.speculative_outer_type,
2507 ctx.speculative_offset,
2508 ctx.speculative_maybe_derived_type,
2509 otr_type);
2511 if (updated && dump_file && (dump_flags & TDF_DETAILS))
2513 fprintf (dump_file, "Updated as: ");
2514 dump (dump_file);
2515 fprintf (dump_file, "\n");
2517 return updated;