Home | History | Annotate | Line # | Download | only in gcc
ipa-polymorphic-call.cc revision 1.1
      1  1.1  mrg /* Analysis of polymorphic call context.
      2  1.1  mrg    Copyright (C) 2013-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Jan Hubicka
      4  1.1  mrg 
      5  1.1  mrg This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      8  1.1  mrg the terms of the GNU General Public License as published by the Free
      9  1.1  mrg Software Foundation; either version 3, or (at your option) any later
     10  1.1  mrg version.
     11  1.1  mrg 
     12  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  1.1  mrg for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License
     18  1.1  mrg along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg #include "config.h"
     22  1.1  mrg #include "system.h"
     23  1.1  mrg #include "coretypes.h"
     24  1.1  mrg #include "backend.h"
     25  1.1  mrg #include "rtl.h"
     26  1.1  mrg #include "tree.h"
     27  1.1  mrg #include "gimple.h"
     28  1.1  mrg #include "tree-pass.h"
     29  1.1  mrg #include "tree-ssa-operands.h"
     30  1.1  mrg #include "streamer-hooks.h"
     31  1.1  mrg #include "cgraph.h"
     32  1.1  mrg #include "data-streamer.h"
     33  1.1  mrg #include "diagnostic.h"
     34  1.1  mrg #include "alias.h"
     35  1.1  mrg #include "fold-const.h"
     36  1.1  mrg #include "calls.h"
     37  1.1  mrg #include "ipa-utils.h"
     38  1.1  mrg #include "tree-dfa.h"
     39  1.1  mrg #include "gimple-pretty-print.h"
     40  1.1  mrg #include "tree-into-ssa.h"
     41  1.1  mrg #include "alloc-pool.h"
     42  1.1  mrg #include "symbol-summary.h"
     43  1.1  mrg #include "symtab-thunks.h"
     44  1.1  mrg 
     45  1.1  mrg /* Return true when TYPE contains an polymorphic type and thus is interesting
     46  1.1  mrg    for devirtualization machinery.  */
     47  1.1  mrg 
     48  1.1  mrg static bool contains_type_p (tree, HOST_WIDE_INT, tree,
     49  1.1  mrg 			     bool consider_placement_new = true,
     50  1.1  mrg 			     bool consider_bases = true);
     51  1.1  mrg 
     52  1.1  mrg bool
     53  1.1  mrg contains_polymorphic_type_p (const_tree type)
     54  1.1  mrg {
     55  1.1  mrg   type = TYPE_MAIN_VARIANT (type);
     56  1.1  mrg 
     57  1.1  mrg   if (RECORD_OR_UNION_TYPE_P (type))
     58  1.1  mrg     {
     59  1.1  mrg       if (TYPE_BINFO (type)
     60  1.1  mrg           && polymorphic_type_binfo_p (TYPE_BINFO (type)))
     61  1.1  mrg 	return true;
     62  1.1  mrg       for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
     63  1.1  mrg 	if (TREE_CODE (fld) == FIELD_DECL
     64  1.1  mrg 	    && !DECL_ARTIFICIAL (fld)
     65  1.1  mrg 	    && contains_polymorphic_type_p (TREE_TYPE (fld)))
     66  1.1  mrg 	  return true;
     67  1.1  mrg       return false;
     68  1.1  mrg     }
     69  1.1  mrg   if (TREE_CODE (type) == ARRAY_TYPE)
     70  1.1  mrg     return contains_polymorphic_type_p (TREE_TYPE (type));
     71  1.1  mrg   return false;
     72  1.1  mrg }
     73  1.1  mrg 
     74  1.1  mrg /* Return true if it seems valid to use placement new to build EXPECTED_TYPE
     75  1.1  mrg    at position CUR_OFFSET within TYPE.
     76  1.1  mrg 
     77  1.1  mrg    POD can be changed to an instance of a polymorphic type by
     78  1.1  mrg    placement new.  Here we play safe and assume that any
     79  1.1  mrg    non-polymorphic type is POD.  */
     80  1.1  mrg bool
     81  1.1  mrg possible_placement_new (tree type, tree expected_type,
     82  1.1  mrg 			HOST_WIDE_INT cur_offset)
     83  1.1  mrg {
     84  1.1  mrg   if (cur_offset < 0)
     85  1.1  mrg     return true;
     86  1.1  mrg   return ((TREE_CODE (type) != RECORD_TYPE
     87  1.1  mrg 	   || !TYPE_BINFO (type)
     88  1.1  mrg 	   || cur_offset >= POINTER_SIZE
     89  1.1  mrg 	   || !polymorphic_type_binfo_p (TYPE_BINFO (type)))
     90  1.1  mrg 	  && (!TYPE_SIZE (type)
     91  1.1  mrg 	      || !tree_fits_shwi_p (TYPE_SIZE (type))
     92  1.1  mrg 	      || (cur_offset
     93  1.1  mrg 		  + (expected_type ? tree_to_uhwi (TYPE_SIZE (expected_type))
     94  1.1  mrg 		     : POINTER_SIZE)
     95  1.1  mrg 		  <= tree_to_uhwi (TYPE_SIZE (type)))));
     96  1.1  mrg }
     97  1.1  mrg 
     98  1.1  mrg /* THIS->OUTER_TYPE is a type of memory object where object of OTR_TYPE
     99  1.1  mrg    is contained at THIS->OFFSET.  Walk the memory representation of
    100  1.1  mrg    THIS->OUTER_TYPE and find the outermost class type that match
    101  1.1  mrg    OTR_TYPE or contain OTR_TYPE as a base.  Update THIS
    102  1.1  mrg    to represent it.
    103  1.1  mrg 
    104  1.1  mrg    If OTR_TYPE is NULL, just find outermost polymorphic type with
    105  1.1  mrg    virtual table present at position OFFSET.
    106  1.1  mrg 
    107  1.1  mrg    For example when THIS represents type
    108  1.1  mrg    class A
    109  1.1  mrg      {
    110  1.1  mrg        int a;
    111  1.1  mrg        class B b;
    112  1.1  mrg      }
    113  1.1  mrg    and we look for type at offset sizeof(int), we end up with B and offset 0.
    114  1.1  mrg    If the same is produced by multiple inheritance, we end up with A and offset
    115  1.1  mrg    sizeof(int).
    116  1.1  mrg 
    117  1.1  mrg    If we cannot find corresponding class, give up by setting
    118  1.1  mrg    THIS->OUTER_TYPE to OTR_TYPE and THIS->OFFSET to NULL.
    119  1.1  mrg    Return true when lookup was successful.
    120  1.1  mrg 
    121  1.1  mrg    When CONSIDER_PLACEMENT_NEW is false, reject contexts that may be made
    122  1.1  mrg    valid only via allocation of new polymorphic type inside by means
    123  1.1  mrg    of placement new.
    124  1.1  mrg 
    125  1.1  mrg    When CONSIDER_BASES is false, only look for actual fields, not base types
    126  1.1  mrg    of TYPE.  */
    127  1.1  mrg 
    128  1.1  mrg bool
    129  1.1  mrg ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type,
    130  1.1  mrg 						       bool consider_placement_new,
    131  1.1  mrg 						       bool consider_bases)
    132  1.1  mrg {
    133  1.1  mrg   tree type = outer_type;
    134  1.1  mrg   HOST_WIDE_INT cur_offset = offset;
    135  1.1  mrg   bool speculative = false;
    136  1.1  mrg   bool size_unknown = false;
    137  1.1  mrg   unsigned HOST_WIDE_INT otr_type_size = POINTER_SIZE;
    138  1.1  mrg 
    139  1.1  mrg   /* Update OUTER_TYPE to match EXPECTED_TYPE if it is not set.  */
    140  1.1  mrg   if (!outer_type)
    141  1.1  mrg     {
    142  1.1  mrg       clear_outer_type (otr_type);
    143  1.1  mrg       type = otr_type;
    144  1.1  mrg       cur_offset = 0;
    145  1.1  mrg     }
    146  1.1  mrg  /* See if OFFSET points inside OUTER_TYPE.  If it does not, we know
    147  1.1  mrg     that the context is either invalid, or the instance type must be
    148  1.1  mrg     derived from OUTER_TYPE.
    149  1.1  mrg 
    150  1.1  mrg     Because the instance type may contain field whose type is of OUTER_TYPE,
    151  1.1  mrg     we cannot derive any effective information about it.
    152  1.1  mrg 
    153  1.1  mrg     TODO: In the case we know all derived types, we can definitely do better
    154  1.1  mrg     here.  */
    155  1.1  mrg   else if (TYPE_SIZE (outer_type)
    156  1.1  mrg 	   && tree_fits_shwi_p (TYPE_SIZE (outer_type))
    157  1.1  mrg 	   && tree_to_shwi (TYPE_SIZE (outer_type)) >= 0
    158  1.1  mrg 	   && tree_to_shwi (TYPE_SIZE (outer_type)) <= offset)
    159  1.1  mrg    {
    160  1.1  mrg      bool der = maybe_derived_type; /* clear_outer_type will reset it.  */
    161  1.1  mrg      bool dyn = dynamic;
    162  1.1  mrg      clear_outer_type (otr_type);
    163  1.1  mrg      type = otr_type;
    164  1.1  mrg      cur_offset = 0;
    165  1.1  mrg 
    166  1.1  mrg      /* If derived type is not allowed, we know that the context is invalid.
    167  1.1  mrg 	For dynamic types, we really do not have information about
    168  1.1  mrg 	size of the memory location.  It is possible that completely
    169  1.1  mrg 	different type is stored after outer_type.  */
    170  1.1  mrg      if (!der && !dyn)
    171  1.1  mrg        {
    172  1.1  mrg 	 clear_speculation ();
    173  1.1  mrg 	 invalid = true;
    174  1.1  mrg 	 return false;
    175  1.1  mrg        }
    176  1.1  mrg    }
    177  1.1  mrg 
    178  1.1  mrg   if (otr_type && TYPE_SIZE (otr_type)
    179  1.1  mrg       && tree_fits_shwi_p (TYPE_SIZE (otr_type)))
    180  1.1  mrg     otr_type_size = tree_to_uhwi (TYPE_SIZE (otr_type));
    181  1.1  mrg 
    182  1.1  mrg   if (!type || offset < 0)
    183  1.1  mrg     goto no_useful_type_info;
    184  1.1  mrg 
    185  1.1  mrg   /* Find the sub-object the constant actually refers to and mark whether it is
    186  1.1  mrg      an artificial one (as opposed to a user-defined one).
    187  1.1  mrg 
    188  1.1  mrg      This loop is performed twice; first time for outer_type and second time
    189  1.1  mrg      for speculative_outer_type.  The second run has SPECULATIVE set.  */
    190  1.1  mrg   while (true)
    191  1.1  mrg     {
    192  1.1  mrg       unsigned HOST_WIDE_INT pos, size;
    193  1.1  mrg       tree fld;
    194  1.1  mrg 
    195  1.1  mrg       /* If we do not know size of TYPE, we need to be more conservative
    196  1.1  mrg          about accepting cases where we cannot find EXPECTED_TYPE.
    197  1.1  mrg 	 Generally the types that do matter here are of constant size.
    198  1.1  mrg 	 Size_unknown case should be very rare.  */
    199  1.1  mrg       if (TYPE_SIZE (type)
    200  1.1  mrg 	  && tree_fits_shwi_p (TYPE_SIZE (type))
    201  1.1  mrg 	  && tree_to_shwi (TYPE_SIZE (type)) >= 0)
    202  1.1  mrg 	size_unknown = false;
    203  1.1  mrg       else
    204  1.1  mrg 	size_unknown = true;
    205  1.1  mrg 
    206  1.1  mrg       /* On a match, just return what we found.  */
    207  1.1  mrg       if ((otr_type
    208  1.1  mrg 	   && types_odr_comparable (type, otr_type)
    209  1.1  mrg 	   && types_same_for_odr (type, otr_type))
    210  1.1  mrg 	  || (!otr_type
    211  1.1  mrg 	      && TREE_CODE (type) == RECORD_TYPE
    212  1.1  mrg 	      && TYPE_BINFO (type)
    213  1.1  mrg 	      && polymorphic_type_binfo_p (TYPE_BINFO (type))))
    214  1.1  mrg 	{
    215  1.1  mrg 	  if (speculative)
    216  1.1  mrg 	    {
    217  1.1  mrg 	      /* If we did not match the offset, just give up on speculation.  */
    218  1.1  mrg 	      if (cur_offset != 0
    219  1.1  mrg 		  /* Also check if speculation did not end up being same as
    220  1.1  mrg 		     non-speculation.  */
    221  1.1  mrg 		  || (types_must_be_same_for_odr (speculative_outer_type,
    222  1.1  mrg 						  outer_type)
    223  1.1  mrg 		      && (maybe_derived_type
    224  1.1  mrg 			  == speculative_maybe_derived_type)))
    225  1.1  mrg 		clear_speculation ();
    226  1.1  mrg 	      return true;
    227  1.1  mrg 	    }
    228  1.1  mrg 	  else
    229  1.1  mrg 	    {
    230  1.1  mrg 	      /* If type is known to be final, do not worry about derived
    231  1.1  mrg 		 types.  Testing it here may help us to avoid speculation.  */
    232  1.1  mrg 	      if (otr_type && TREE_CODE (outer_type) == RECORD_TYPE
    233  1.1  mrg 		  && (!in_lto_p || odr_type_p (outer_type))
    234  1.1  mrg 		  && type_with_linkage_p (outer_type)
    235  1.1  mrg 		  && type_known_to_have_no_derivations_p (outer_type))
    236  1.1  mrg 		maybe_derived_type = false;
    237  1.1  mrg 
    238  1.1  mrg 	      /* Type cannot contain itself on an non-zero offset.  In that case
    239  1.1  mrg 		 just give up.  Still accept the case where size is now known.
    240  1.1  mrg 		 Either the second copy may appear past the end of type or within
    241  1.1  mrg 		 the non-POD buffer located inside the variably sized type
    242  1.1  mrg 		 itself.  */
    243  1.1  mrg 	      if (cur_offset != 0)
    244  1.1  mrg 		goto no_useful_type_info;
    245  1.1  mrg 	      /* If we determined type precisely or we have no clue on
    246  1.1  mrg  		 speculation, we are done.  */
    247  1.1  mrg 	      if (!maybe_derived_type || !speculative_outer_type
    248  1.1  mrg 		  || !speculation_consistent_p (speculative_outer_type,
    249  1.1  mrg 					        speculative_offset,
    250  1.1  mrg 					        speculative_maybe_derived_type,
    251  1.1  mrg 						otr_type))
    252  1.1  mrg 		{
    253  1.1  mrg 		  clear_speculation ();
    254  1.1  mrg 	          return true;
    255  1.1  mrg 		}
    256  1.1  mrg 	      /* Otherwise look into speculation now.  */
    257  1.1  mrg 	      else
    258  1.1  mrg 		{
    259  1.1  mrg 		  speculative = true;
    260  1.1  mrg 		  type = speculative_outer_type;
    261  1.1  mrg 		  cur_offset = speculative_offset;
    262  1.1  mrg 		  continue;
    263  1.1  mrg 		}
    264  1.1  mrg 	    }
    265  1.1  mrg 	}
    266  1.1  mrg 
    267  1.1  mrg       /* Walk fields and find corresponding on at OFFSET.  */
    268  1.1  mrg       if (TREE_CODE (type) == RECORD_TYPE)
    269  1.1  mrg 	{
    270  1.1  mrg 	  for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
    271  1.1  mrg 	    {
    272  1.1  mrg 	      if (TREE_CODE (fld) != FIELD_DECL
    273  1.1  mrg 		  || TREE_TYPE (fld) == error_mark_node)
    274  1.1  mrg 		continue;
    275  1.1  mrg 
    276  1.1  mrg 	      pos = int_bit_position (fld);
    277  1.1  mrg 	      if (pos > (unsigned HOST_WIDE_INT)cur_offset)
    278  1.1  mrg 		continue;
    279  1.1  mrg 
    280  1.1  mrg 	      /* Do not consider vptr itself.  Not even for placement new.  */
    281  1.1  mrg 	      if (!pos && DECL_ARTIFICIAL (fld)
    282  1.1  mrg 		  && POINTER_TYPE_P (TREE_TYPE (fld))
    283  1.1  mrg 		  && TYPE_BINFO (type)
    284  1.1  mrg 		  && polymorphic_type_binfo_p (TYPE_BINFO (type)))
    285  1.1  mrg 		continue;
    286  1.1  mrg 
    287  1.1  mrg 	      if (!DECL_SIZE (fld) || !tree_fits_uhwi_p (DECL_SIZE (fld)))
    288  1.1  mrg 		goto no_useful_type_info;
    289  1.1  mrg 	      size = tree_to_uhwi (DECL_SIZE (fld));
    290  1.1  mrg 
    291  1.1  mrg 	      /* We can always skip types smaller than pointer size:
    292  1.1  mrg 		 those cannot contain a virtual table pointer.
    293  1.1  mrg 
    294  1.1  mrg 		 Disqualifying fields that are too small to fit OTR_TYPE
    295  1.1  mrg 		 saves work needed to walk them for no benefit.
    296  1.1  mrg 		 Because of the way the bases are packed into a class, the
    297  1.1  mrg 		 field's size may be smaller than type size, so it needs
    298  1.1  mrg 		 to be done with a care.  */
    299  1.1  mrg 
    300  1.1  mrg 	      if (pos <= (unsigned HOST_WIDE_INT)cur_offset
    301  1.1  mrg 		  && (pos + size) >= (unsigned HOST_WIDE_INT)cur_offset
    302  1.1  mrg 				     + POINTER_SIZE
    303  1.1  mrg 		  && (!otr_type
    304  1.1  mrg 		      || !TYPE_SIZE (TREE_TYPE (fld))
    305  1.1  mrg 		      || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (fld)))
    306  1.1  mrg 		      || (pos + tree_to_uhwi (TYPE_SIZE (TREE_TYPE (fld))))
    307  1.1  mrg 			  >= cur_offset + otr_type_size))
    308  1.1  mrg 		break;
    309  1.1  mrg 	    }
    310  1.1  mrg 
    311  1.1  mrg 	  if (!fld)
    312  1.1  mrg 	    goto no_useful_type_info;
    313  1.1  mrg 
    314  1.1  mrg 	  type = TYPE_MAIN_VARIANT (TREE_TYPE (fld));
    315  1.1  mrg 	  cur_offset -= pos;
    316  1.1  mrg 	  /* DECL_ARTIFICIAL represents a basetype.  */
    317  1.1  mrg 	  if (!DECL_ARTIFICIAL (fld))
    318  1.1  mrg 	    {
    319  1.1  mrg 	      if (!speculative)
    320  1.1  mrg 		{
    321  1.1  mrg 		  outer_type = type;
    322  1.1  mrg 		  offset = cur_offset;
    323  1.1  mrg 		  /* As soon as we see an field containing the type,
    324  1.1  mrg 		     we know we are not looking for derivations.  */
    325  1.1  mrg 		  maybe_derived_type = false;
    326  1.1  mrg 		}
    327  1.1  mrg 	      else
    328  1.1  mrg 		{
    329  1.1  mrg 		  speculative_outer_type = type;
    330  1.1  mrg 		  speculative_offset = cur_offset;
    331  1.1  mrg 		  speculative_maybe_derived_type = false;
    332  1.1  mrg 		}
    333  1.1  mrg 	    }
    334  1.1  mrg 	  else if (!consider_bases)
    335  1.1  mrg 	    goto no_useful_type_info;
    336  1.1  mrg 	}
    337  1.1  mrg       else if (TREE_CODE (type) == ARRAY_TYPE)
    338  1.1  mrg 	{
    339  1.1  mrg 	  tree subtype = TYPE_MAIN_VARIANT (TREE_TYPE (type));
    340  1.1  mrg 
    341  1.1  mrg 	  /* Give up if we don't know array field size.
    342  1.1  mrg 	     Also give up on non-polymorphic types as they are used
    343  1.1  mrg 	     as buffers for placement new.  */
    344  1.1  mrg 	  if (!TYPE_SIZE (subtype)
    345  1.1  mrg 	      || !tree_fits_shwi_p (TYPE_SIZE (subtype))
    346  1.1  mrg 	      || tree_to_shwi (TYPE_SIZE (subtype)) <= 0
    347  1.1  mrg 	      || !contains_polymorphic_type_p (subtype))
    348  1.1  mrg 	    goto no_useful_type_info;
    349  1.1  mrg 
    350  1.1  mrg 	  HOST_WIDE_INT new_offset = cur_offset % tree_to_shwi (TYPE_SIZE (subtype));
    351  1.1  mrg 
    352  1.1  mrg 	  /* We may see buffer for placement new.  In this case the expected type
    353  1.1  mrg 	     can be bigger than the subtype.  */
    354  1.1  mrg 	  if (TYPE_SIZE (subtype)
    355  1.1  mrg 	      && (cur_offset + otr_type_size
    356  1.1  mrg 		  > tree_to_uhwi (TYPE_SIZE (subtype))))
    357  1.1  mrg 	    goto no_useful_type_info;
    358  1.1  mrg 
    359  1.1  mrg 	  cur_offset = new_offset;
    360  1.1  mrg 	  type = TYPE_MAIN_VARIANT (subtype);
    361  1.1  mrg 	  if (!speculative)
    362  1.1  mrg 	    {
    363  1.1  mrg 	      outer_type = type;
    364  1.1  mrg 	      offset = cur_offset;
    365  1.1  mrg 	      maybe_derived_type = false;
    366  1.1  mrg 	    }
    367  1.1  mrg 	  else
    368  1.1  mrg 	    {
    369  1.1  mrg 	      speculative_outer_type = type;
    370  1.1  mrg 	      speculative_offset = cur_offset;
    371  1.1  mrg 	      speculative_maybe_derived_type = false;
    372  1.1  mrg 	    }
    373  1.1  mrg 	}
    374  1.1  mrg       /* Give up on anything else.  */
    375  1.1  mrg       else
    376  1.1  mrg 	{
    377  1.1  mrg no_useful_type_info:
    378  1.1  mrg 	  if (maybe_derived_type && !speculative
    379  1.1  mrg 	      && TREE_CODE (outer_type) == RECORD_TYPE
    380  1.1  mrg 	      && TREE_CODE (otr_type) == RECORD_TYPE
    381  1.1  mrg 	      && TYPE_BINFO (otr_type)
    382  1.1  mrg 	      && !offset
    383  1.1  mrg 	      && get_binfo_at_offset (TYPE_BINFO (otr_type), 0, outer_type))
    384  1.1  mrg 	    {
    385  1.1  mrg 	      clear_outer_type (otr_type);
    386  1.1  mrg 	      if (!speculative_outer_type
    387  1.1  mrg 		  || !speculation_consistent_p (speculative_outer_type,
    388  1.1  mrg 						speculative_offset,
    389  1.1  mrg 					        speculative_maybe_derived_type,
    390  1.1  mrg 						otr_type))
    391  1.1  mrg 		clear_speculation ();
    392  1.1  mrg 	      if (speculative_outer_type)
    393  1.1  mrg 		{
    394  1.1  mrg 		  speculative = true;
    395  1.1  mrg 		  type = speculative_outer_type;
    396  1.1  mrg 		  cur_offset = speculative_offset;
    397  1.1  mrg 		}
    398  1.1  mrg 	      else
    399  1.1  mrg 		return true;
    400  1.1  mrg 	    }
    401  1.1  mrg 	  /* We found no way to embed EXPECTED_TYPE in TYPE.
    402  1.1  mrg 	     We still permit two special cases - placement new and
    403  1.1  mrg 	     the case of variadic types containing themselves.  */
    404  1.1  mrg 	  if (!speculative
    405  1.1  mrg 	      && consider_placement_new
    406  1.1  mrg 	      && (size_unknown || !type || maybe_derived_type
    407  1.1  mrg 		  || possible_placement_new (type, otr_type, cur_offset)))
    408  1.1  mrg 	    {
    409  1.1  mrg 	      /* In these weird cases we want to accept the context.
    410  1.1  mrg 		 In non-speculative run we have no useful outer_type info
    411  1.1  mrg 		 (TODO: we may eventually want to record upper bound on the
    412  1.1  mrg 		  type size that can be used to prune the walk),
    413  1.1  mrg 		 but we still want to consider speculation that may
    414  1.1  mrg 		 give useful info.  */
    415  1.1  mrg 	      if (!speculative)
    416  1.1  mrg 		{
    417  1.1  mrg 		  clear_outer_type (otr_type);
    418  1.1  mrg 		  if (!speculative_outer_type
    419  1.1  mrg 		      || !speculation_consistent_p (speculative_outer_type,
    420  1.1  mrg 						    speculative_offset,
    421  1.1  mrg 						    speculative_maybe_derived_type,
    422  1.1  mrg 						    otr_type))
    423  1.1  mrg 		    clear_speculation ();
    424  1.1  mrg 		  if (speculative_outer_type)
    425  1.1  mrg 		    {
    426  1.1  mrg 		      speculative = true;
    427  1.1  mrg 		      type = speculative_outer_type;
    428  1.1  mrg 		      cur_offset = speculative_offset;
    429  1.1  mrg 		    }
    430  1.1  mrg 		  else
    431  1.1  mrg 		    return true;
    432  1.1  mrg 		}
    433  1.1  mrg 	      else
    434  1.1  mrg 		{
    435  1.1  mrg 		  clear_speculation ();
    436  1.1  mrg 	          return true;
    437  1.1  mrg 		}
    438  1.1  mrg 	    }
    439  1.1  mrg 	  else
    440  1.1  mrg 	    {
    441  1.1  mrg 	      clear_speculation ();
    442  1.1  mrg 	      if (speculative)
    443  1.1  mrg 		return true;
    444  1.1  mrg 	      clear_outer_type (otr_type);
    445  1.1  mrg 	      invalid = true;
    446  1.1  mrg 	      return false;
    447  1.1  mrg 	    }
    448  1.1  mrg 	}
    449  1.1  mrg     }
    450  1.1  mrg }
    451  1.1  mrg 
    452  1.1  mrg /* Return true if OUTER_TYPE contains OTR_TYPE at OFFSET.
    453  1.1  mrg    CONSIDER_PLACEMENT_NEW makes function to accept cases where OTR_TYPE can
    454  1.1  mrg    be built within OUTER_TYPE by means of placement new.  CONSIDER_BASES makes
    455  1.1  mrg    function to accept cases where OTR_TYPE appears as base of OUTER_TYPE or as
    456  1.1  mrg    base of one of fields of OUTER_TYPE.  */
    457  1.1  mrg 
    458  1.1  mrg static bool
    459  1.1  mrg contains_type_p (tree outer_type, HOST_WIDE_INT offset,
    460  1.1  mrg 		 tree otr_type,
    461  1.1  mrg 		 bool consider_placement_new,
    462  1.1  mrg 		 bool consider_bases)
    463  1.1  mrg {
    464  1.1  mrg   ipa_polymorphic_call_context context;
    465  1.1  mrg 
    466  1.1  mrg   /* Check that type is within range.  */
    467  1.1  mrg   if (offset < 0)
    468  1.1  mrg     return false;
    469  1.1  mrg 
    470  1.1  mrg   /* PR ipa/71207
    471  1.1  mrg      As OUTER_TYPE can be a type which has a diamond virtual inheritance,
    472  1.1  mrg      it's not necessary that INNER_TYPE will fit within OUTER_TYPE with
    473  1.1  mrg      a given offset.  It can happen that INNER_TYPE also contains a base object,
    474  1.1  mrg      however it would point to the same instance in the OUTER_TYPE.  */
    475  1.1  mrg 
    476  1.1  mrg   context.offset = offset;
    477  1.1  mrg   context.outer_type = TYPE_MAIN_VARIANT (outer_type);
    478  1.1  mrg   context.maybe_derived_type = false;
    479  1.1  mrg   context.dynamic = false;
    480  1.1  mrg   return context.restrict_to_inner_class (otr_type, consider_placement_new,
    481  1.1  mrg 					  consider_bases);
    482  1.1  mrg }
    483  1.1  mrg 
    484  1.1  mrg 
    485  1.1  mrg /* Return a FUNCTION_DECL if FN represent a constructor or destructor.
    486  1.1  mrg    If CHECK_CLONES is true, also check for clones of ctor/dtors.  */
    487  1.1  mrg 
    488  1.1  mrg tree
    489  1.1  mrg polymorphic_ctor_dtor_p (tree fn, bool check_clones)
    490  1.1  mrg {
    491  1.1  mrg   if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
    492  1.1  mrg       || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
    493  1.1  mrg     {
    494  1.1  mrg       if (!check_clones)
    495  1.1  mrg 	return NULL_TREE;
    496  1.1  mrg 
    497  1.1  mrg       /* Watch for clones where we constant propagated the first
    498  1.1  mrg 	 argument (pointer to the instance).  */
    499  1.1  mrg       fn = DECL_ABSTRACT_ORIGIN (fn);
    500  1.1  mrg       if (!fn
    501  1.1  mrg 	  || TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
    502  1.1  mrg 	  || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
    503  1.1  mrg 	return NULL_TREE;
    504  1.1  mrg     }
    505  1.1  mrg 
    506  1.1  mrg   if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
    507  1.1  mrg     return NULL_TREE;
    508  1.1  mrg 
    509  1.1  mrg   return fn;
    510  1.1  mrg }
    511  1.1  mrg 
    512  1.1  mrg /* Return a FUNCTION_DECL if BLOCK represents a constructor or destructor.
    513  1.1  mrg    If CHECK_CLONES is true, also check for clones of ctor/dtors.  */
    514  1.1  mrg 
    515  1.1  mrg tree
    516  1.1  mrg inlined_polymorphic_ctor_dtor_block_p (tree block, bool check_clones)
    517  1.1  mrg {
    518  1.1  mrg   tree fn = block_ultimate_origin (block);
    519  1.1  mrg   if (fn == NULL || TREE_CODE (fn) != FUNCTION_DECL)
    520  1.1  mrg     return NULL_TREE;
    521  1.1  mrg 
    522  1.1  mrg   return polymorphic_ctor_dtor_p (fn, check_clones);
    523  1.1  mrg }
    524  1.1  mrg 
    525  1.1  mrg 
    526  1.1  mrg /* We know that the instance is stored in variable or parameter
    527  1.1  mrg    (not dynamically allocated) and we want to disprove the fact
    528  1.1  mrg    that it may be in construction at invocation of CALL.
    529  1.1  mrg 
    530  1.1  mrg    BASE represents memory location where instance is stored.
    531  1.1  mrg    If BASE is NULL, it is assumed to be global memory.
    532  1.1  mrg    OUTER_TYPE is known type of the instance or NULL if not
    533  1.1  mrg    known.
    534  1.1  mrg 
    535  1.1  mrg    For the variable to be in construction we actually need to
    536  1.1  mrg    be in constructor of corresponding global variable or
    537  1.1  mrg    the inline stack of CALL must contain the constructor.
    538  1.1  mrg    Check this condition.  This check works safely only before
    539  1.1  mrg    IPA passes, because inline stacks may become out of date
    540  1.1  mrg    later.  */
    541  1.1  mrg 
    542  1.1  mrg bool
    543  1.1  mrg decl_maybe_in_construction_p (tree base, tree outer_type,
    544  1.1  mrg 			      gimple *call, tree function)
    545  1.1  mrg {
    546  1.1  mrg   if (outer_type)
    547  1.1  mrg     outer_type = TYPE_MAIN_VARIANT (outer_type);
    548  1.1  mrg   gcc_assert (!base || DECL_P (base));
    549  1.1  mrg 
    550  1.1  mrg   /* After inlining the code unification optimizations may invalidate
    551  1.1  mrg      inline stacks.  Also we need to give up on global variables after
    552  1.1  mrg      IPA, because addresses of these may have been propagated to their
    553  1.1  mrg      constructors.  */
    554  1.1  mrg   if (DECL_STRUCT_FUNCTION (function)->after_inlining)
    555  1.1  mrg     return true;
    556  1.1  mrg 
    557  1.1  mrg   /* Pure functions cannot do any changes on the dynamic type;
    558  1.1  mrg      that require writing to memory.  */
    559  1.1  mrg   if ((!base || !auto_var_in_fn_p (base, function))
    560  1.1  mrg       && flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
    561  1.1  mrg     return false;
    562  1.1  mrg 
    563  1.1  mrg   bool check_clones = !base || is_global_var (base);
    564  1.1  mrg   for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
    565  1.1  mrg        block = BLOCK_SUPERCONTEXT (block))
    566  1.1  mrg     if (tree fn = inlined_polymorphic_ctor_dtor_block_p (block, check_clones))
    567  1.1  mrg       {
    568  1.1  mrg 	tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
    569  1.1  mrg 
    570  1.1  mrg 	if (!outer_type || !types_odr_comparable (type, outer_type))
    571  1.1  mrg 	  {
    572  1.1  mrg 	    if (TREE_CODE (type) == RECORD_TYPE
    573  1.1  mrg 		&& TYPE_BINFO (type)
    574  1.1  mrg 		&& polymorphic_type_binfo_p (TYPE_BINFO (type)))
    575  1.1  mrg 	      return true;
    576  1.1  mrg 	  }
    577  1.1  mrg  	else if (types_same_for_odr (type, outer_type))
    578  1.1  mrg 	  return true;
    579  1.1  mrg       }
    580  1.1  mrg 
    581  1.1  mrg   if (!base || (VAR_P (base) && is_global_var (base)))
    582  1.1  mrg     {
    583  1.1  mrg       if (TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
    584  1.1  mrg 	  || (!DECL_CXX_CONSTRUCTOR_P (function)
    585  1.1  mrg 	      && !DECL_CXX_DESTRUCTOR_P (function)))
    586  1.1  mrg 	{
    587  1.1  mrg 	  if (!DECL_ABSTRACT_ORIGIN (function))
    588  1.1  mrg 	    return false;
    589  1.1  mrg 	  /* Watch for clones where we constant propagated the first
    590  1.1  mrg 	     argument (pointer to the instance).  */
    591  1.1  mrg 	  function = DECL_ABSTRACT_ORIGIN (function);
    592  1.1  mrg 	  if (!function
    593  1.1  mrg 	      || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
    594  1.1  mrg 	      || (!DECL_CXX_CONSTRUCTOR_P (function)
    595  1.1  mrg 		  && !DECL_CXX_DESTRUCTOR_P (function)))
    596  1.1  mrg 	    return false;
    597  1.1  mrg 	}
    598  1.1  mrg       tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (function));
    599  1.1  mrg       if (!outer_type || !types_odr_comparable (type, outer_type))
    600  1.1  mrg 	{
    601  1.1  mrg 	  if (TREE_CODE (type) == RECORD_TYPE
    602  1.1  mrg 	      && TYPE_BINFO (type)
    603  1.1  mrg 	      && polymorphic_type_binfo_p (TYPE_BINFO (type)))
    604  1.1  mrg 	    return true;
    605  1.1  mrg 	}
    606  1.1  mrg       else if (types_same_for_odr (type, outer_type))
    607  1.1  mrg 	return true;
    608  1.1  mrg     }
    609  1.1  mrg   return false;
    610  1.1  mrg }
    611  1.1  mrg 
    612  1.1  mrg /* Dump human readable context to F.  If NEWLINE is true, it will be terminated
    613  1.1  mrg    by a newline.  */
    614  1.1  mrg 
    615  1.1  mrg void
    616  1.1  mrg ipa_polymorphic_call_context::dump (FILE *f, bool newline) const
    617  1.1  mrg {
    618  1.1  mrg   fprintf (f, "    ");
    619  1.1  mrg   if (invalid)
    620  1.1  mrg     fprintf (f, "Call is known to be undefined");
    621  1.1  mrg   else
    622  1.1  mrg     {
    623  1.1  mrg       if (useless_p ())
    624  1.1  mrg 	fprintf (f, "nothing known");
    625  1.1  mrg       if (outer_type || offset)
    626  1.1  mrg 	{
    627  1.1  mrg 	  fprintf (f, "Outer type%s:", dynamic ? " (dynamic)":"");
    628  1.1  mrg 	  print_generic_expr (f, outer_type, TDF_SLIM);
    629  1.1  mrg 	  if (maybe_derived_type)
    630  1.1  mrg 	    fprintf (f, " (or a derived type)");
    631  1.1  mrg 	  if (maybe_in_construction)
    632  1.1  mrg 	    fprintf (f, " (maybe in construction)");
    633  1.1  mrg 	  fprintf (f, " offset " HOST_WIDE_INT_PRINT_DEC,
    634  1.1  mrg 		   offset);
    635  1.1  mrg 	}
    636  1.1  mrg       if (speculative_outer_type)
    637  1.1  mrg 	{
    638  1.1  mrg 	  if (outer_type || offset)
    639  1.1  mrg 	    fprintf (f, " ");
    640  1.1  mrg 	  fprintf (f, "Speculative outer type:");
    641  1.1  mrg 	  print_generic_expr (f, speculative_outer_type, TDF_SLIM);
    642  1.1  mrg 	  if (speculative_maybe_derived_type)
    643  1.1  mrg 	    fprintf (f, " (or a derived type)");
    644  1.1  mrg 	  fprintf (f, " at offset " HOST_WIDE_INT_PRINT_DEC,
    645  1.1  mrg 		   speculative_offset);
    646  1.1  mrg 	}
    647  1.1  mrg     }
    648  1.1  mrg   if (newline)
    649  1.1  mrg     fprintf(f, "\n");
    650  1.1  mrg }
    651  1.1  mrg 
    652  1.1  mrg /* Print context to stderr.  */
    653  1.1  mrg 
    654  1.1  mrg void
    655  1.1  mrg ipa_polymorphic_call_context::debug () const
    656  1.1  mrg {
    657  1.1  mrg   dump (stderr);
    658  1.1  mrg }
    659  1.1  mrg 
    660  1.1  mrg /* Stream out the context to OB.  */
    661  1.1  mrg 
    662  1.1  mrg void
    663  1.1  mrg ipa_polymorphic_call_context::stream_out (struct output_block *ob) const
    664  1.1  mrg {
    665  1.1  mrg   struct bitpack_d bp = bitpack_create (ob->main_stream);
    666  1.1  mrg 
    667  1.1  mrg   bp_pack_value (&bp, invalid, 1);
    668  1.1  mrg   bp_pack_value (&bp, maybe_in_construction, 1);
    669  1.1  mrg   bp_pack_value (&bp, maybe_derived_type, 1);
    670  1.1  mrg   bp_pack_value (&bp, speculative_maybe_derived_type, 1);
    671  1.1  mrg   bp_pack_value (&bp, dynamic, 1);
    672  1.1  mrg   bp_pack_value (&bp, outer_type != NULL, 1);
    673  1.1  mrg   bp_pack_value (&bp, offset != 0, 1);
    674  1.1  mrg   bp_pack_value (&bp, speculative_outer_type != NULL, 1);
    675  1.1  mrg   streamer_write_bitpack (&bp);
    676  1.1  mrg 
    677  1.1  mrg   if (outer_type != NULL)
    678  1.1  mrg     stream_write_tree (ob, outer_type, true);
    679  1.1  mrg   if (offset)
    680  1.1  mrg     streamer_write_hwi (ob, offset);
    681  1.1  mrg   if (speculative_outer_type != NULL)
    682  1.1  mrg     {
    683  1.1  mrg       stream_write_tree (ob, speculative_outer_type, true);
    684  1.1  mrg       streamer_write_hwi (ob, speculative_offset);
    685  1.1  mrg     }
    686  1.1  mrg   else
    687  1.1  mrg     gcc_assert (!speculative_offset);
    688  1.1  mrg }
    689  1.1  mrg 
    690  1.1  mrg /* Stream in the context from IB and DATA_IN.  */
    691  1.1  mrg 
    692  1.1  mrg void
    693  1.1  mrg ipa_polymorphic_call_context::stream_in (class lto_input_block *ib,
    694  1.1  mrg 					 class data_in *data_in)
    695  1.1  mrg {
    696  1.1  mrg   struct bitpack_d bp = streamer_read_bitpack (ib);
    697  1.1  mrg 
    698  1.1  mrg   invalid = bp_unpack_value (&bp, 1);
    699  1.1  mrg   maybe_in_construction = bp_unpack_value (&bp, 1);
    700  1.1  mrg   maybe_derived_type = bp_unpack_value (&bp, 1);
    701  1.1  mrg   speculative_maybe_derived_type = bp_unpack_value (&bp, 1);
    702  1.1  mrg   dynamic = bp_unpack_value (&bp, 1);
    703  1.1  mrg   bool outer_type_p = bp_unpack_value (&bp, 1);
    704  1.1  mrg   bool offset_p = bp_unpack_value (&bp, 1);
    705  1.1  mrg   bool speculative_outer_type_p = bp_unpack_value (&bp, 1);
    706  1.1  mrg 
    707  1.1  mrg   if (outer_type_p)
    708  1.1  mrg     outer_type = stream_read_tree (ib, data_in);
    709  1.1  mrg   else
    710  1.1  mrg     outer_type = NULL;
    711  1.1  mrg   if (offset_p)
    712  1.1  mrg     offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
    713  1.1  mrg   else
    714  1.1  mrg     offset = 0;
    715  1.1  mrg   if (speculative_outer_type_p)
    716  1.1  mrg     {
    717  1.1  mrg       speculative_outer_type = stream_read_tree (ib, data_in);
    718  1.1  mrg       speculative_offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
    719  1.1  mrg     }
    720  1.1  mrg   else
    721  1.1  mrg     {
    722  1.1  mrg       speculative_outer_type = NULL;
    723  1.1  mrg       speculative_offset = 0;
    724  1.1  mrg     }
    725  1.1  mrg }
    726  1.1  mrg 
    727  1.1  mrg /* Produce polymorphic call context for call method of instance
    728  1.1  mrg    that is located within BASE (that is assumed to be a decl) at offset OFF. */
    729  1.1  mrg 
    730  1.1  mrg void
    731  1.1  mrg ipa_polymorphic_call_context::set_by_decl (tree base, HOST_WIDE_INT off)
    732  1.1  mrg {
    733  1.1  mrg   gcc_assert (DECL_P (base));
    734  1.1  mrg   clear_speculation ();
    735  1.1  mrg 
    736  1.1  mrg   if (!contains_polymorphic_type_p (TREE_TYPE (base)))
    737  1.1  mrg     {
    738  1.1  mrg       clear_outer_type ();
    739  1.1  mrg       offset = off;
    740  1.1  mrg       return;
    741  1.1  mrg     }
    742  1.1  mrg   outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (base));
    743  1.1  mrg   offset = off;
    744  1.1  mrg   /* Make very conservative assumption that all objects
    745  1.1  mrg      may be in construction.
    746  1.1  mrg 
    747  1.1  mrg      It is up to caller to revisit this via
    748  1.1  mrg      get_dynamic_type or decl_maybe_in_construction_p.  */
    749  1.1  mrg   maybe_in_construction = true;
    750  1.1  mrg   maybe_derived_type = false;
    751  1.1  mrg   dynamic = false;
    752  1.1  mrg }
    753  1.1  mrg 
    754  1.1  mrg /* CST is an invariant (address of decl), try to get meaningful
    755  1.1  mrg    polymorphic call context for polymorphic call of method
    756  1.1  mrg    if instance of OTR_TYPE that is located at offset OFF of this invariant.
    757  1.1  mrg    Return FALSE if nothing meaningful can be found.  */
    758  1.1  mrg 
    759  1.1  mrg bool
    760  1.1  mrg ipa_polymorphic_call_context::set_by_invariant (tree cst,
    761  1.1  mrg 						tree otr_type,
    762  1.1  mrg 						HOST_WIDE_INT off)
    763  1.1  mrg {
    764  1.1  mrg   poly_int64 offset2, size, max_size;
    765  1.1  mrg   bool reverse;
    766  1.1  mrg   tree base;
    767  1.1  mrg 
    768  1.1  mrg   invalid = false;
    769  1.1  mrg   off = 0;
    770  1.1  mrg   clear_outer_type (otr_type);
    771  1.1  mrg 
    772  1.1  mrg   if (TREE_CODE (cst) != ADDR_EXPR)
    773  1.1  mrg     return false;
    774  1.1  mrg 
    775  1.1  mrg   cst = TREE_OPERAND (cst, 0);
    776  1.1  mrg   base = get_ref_base_and_extent (cst, &offset2, &size, &max_size, &reverse);
    777  1.1  mrg   if (!DECL_P (base) || !known_size_p (max_size) || maybe_ne (max_size, size))
    778  1.1  mrg     return false;
    779  1.1  mrg 
    780  1.1  mrg   /* Only type inconsistent programs can have otr_type that is
    781  1.1  mrg      not part of outer type.  */
    782  1.1  mrg   if (otr_type && !contains_type_p (TREE_TYPE (base), off, otr_type))
    783  1.1  mrg     return false;
    784  1.1  mrg 
    785  1.1  mrg   set_by_decl (base, off);
    786  1.1  mrg   return true;
    787  1.1  mrg }
    788  1.1  mrg 
    789  1.1  mrg /* See if OP is SSA name initialized as a copy or by single assignment.
    790  1.1  mrg    If so, walk the SSA graph up.  Because simple PHI conditional is considered
    791  1.1  mrg    copy, GLOBAL_VISITED may be used to avoid infinite loop walking the SSA
    792  1.1  mrg    graph.  */
    793  1.1  mrg 
    794  1.1  mrg static tree
    795  1.1  mrg walk_ssa_copies (tree op, hash_set<tree> **global_visited = NULL)
    796  1.1  mrg {
    797  1.1  mrg   hash_set <tree> *visited = NULL;
    798  1.1  mrg   STRIP_NOPS (op);
    799  1.1  mrg   while (TREE_CODE (op) == SSA_NAME
    800  1.1  mrg 	 && !SSA_NAME_IS_DEFAULT_DEF (op)
    801  1.1  mrg 	 /* We might be called via fold_stmt during cfgcleanup where
    802  1.1  mrg 	    SSA form need not be up-to-date.  */
    803  1.1  mrg 	 && !name_registered_for_update_p (op)
    804  1.1  mrg 	 && (gimple_assign_single_p (SSA_NAME_DEF_STMT (op))
    805  1.1  mrg 	     || gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI))
    806  1.1  mrg     {
    807  1.1  mrg       if (global_visited)
    808  1.1  mrg 	{
    809  1.1  mrg 	  if (!*global_visited)
    810  1.1  mrg 	    *global_visited = new hash_set<tree>;
    811  1.1  mrg 	  if ((*global_visited)->add (op))
    812  1.1  mrg 	    goto done;
    813  1.1  mrg 	}
    814  1.1  mrg       else
    815  1.1  mrg 	{
    816  1.1  mrg 	  if (!visited)
    817  1.1  mrg 	    visited = new hash_set<tree>;
    818  1.1  mrg 	  if (visited->add (op))
    819  1.1  mrg 	    goto done;
    820  1.1  mrg 	}
    821  1.1  mrg       /* Special case
    822  1.1  mrg 	 if (ptr == 0)
    823  1.1  mrg 	   ptr = 0;
    824  1.1  mrg 	 else
    825  1.1  mrg 	   ptr = ptr.foo;
    826  1.1  mrg 	 This pattern is implicitly produced for casts to non-primary
    827  1.1  mrg 	 bases.  When doing context analysis, we do not really care
    828  1.1  mrg 	 about the case pointer is NULL, because the call will be
    829  1.1  mrg 	 undefined anyway.  */
    830  1.1  mrg       if (gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI)
    831  1.1  mrg 	{
    832  1.1  mrg 	  gimple *phi = SSA_NAME_DEF_STMT (op);
    833  1.1  mrg 
    834  1.1  mrg 	  if (gimple_phi_num_args (phi) > 2)
    835  1.1  mrg 	    goto done;
    836  1.1  mrg 	  if (gimple_phi_num_args (phi) == 1)
    837  1.1  mrg 	    op = gimple_phi_arg_def (phi, 0);
    838  1.1  mrg 	  else if (integer_zerop (gimple_phi_arg_def (phi, 0)))
    839  1.1  mrg 	    op = gimple_phi_arg_def (phi, 1);
    840  1.1  mrg 	  else if (integer_zerop (gimple_phi_arg_def (phi, 1)))
    841  1.1  mrg 	    op = gimple_phi_arg_def (phi, 0);
    842  1.1  mrg 	  else
    843  1.1  mrg 	    goto done;
    844  1.1  mrg 	}
    845  1.1  mrg       else
    846  1.1  mrg 	{
    847  1.1  mrg 	  if (gimple_assign_load_p (SSA_NAME_DEF_STMT (op)))
    848  1.1  mrg 	    goto done;
    849  1.1  mrg 	  op = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op));
    850  1.1  mrg 	}
    851  1.1  mrg       STRIP_NOPS (op);
    852  1.1  mrg     }
    853  1.1  mrg done:
    854  1.1  mrg   if (visited)
    855  1.1  mrg     delete (visited);
    856  1.1  mrg   return op;
    857  1.1  mrg }
    858  1.1  mrg 
    859  1.1  mrg /* Create polymorphic call context from IP invariant CST.
    860  1.1  mrg    This is typically &global_var.
    861  1.1  mrg    OTR_TYPE specify type of polymorphic call or NULL if unknown, OFF
    862  1.1  mrg    is offset of call.  */
    863  1.1  mrg 
    864  1.1  mrg ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree cst,
    865  1.1  mrg 							    tree otr_type,
    866  1.1  mrg 							    HOST_WIDE_INT off)
    867  1.1  mrg {
    868  1.1  mrg   clear_speculation ();
    869  1.1  mrg   set_by_invariant (cst, otr_type, off);
    870  1.1  mrg }
    871  1.1  mrg 
    872  1.1  mrg /* Build context for pointer REF contained in FNDECL at statement STMT.
    873  1.1  mrg    if INSTANCE is non-NULL, return pointer to the object described by
    874  1.1  mrg    the context or DECL where context is contained in.  */
    875  1.1  mrg 
    876  1.1  mrg ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl,
    877  1.1  mrg 							    tree ref,
    878  1.1  mrg 							    gimple *stmt,
    879  1.1  mrg 							    tree *instance)
    880  1.1  mrg {
    881  1.1  mrg   tree otr_type = NULL;
    882  1.1  mrg   tree base_pointer;
    883  1.1  mrg   hash_set <tree> *visited = NULL;
    884  1.1  mrg 
    885  1.1  mrg   if (TREE_CODE (ref) == OBJ_TYPE_REF)
    886  1.1  mrg     {
    887  1.1  mrg       otr_type = obj_type_ref_class (ref);
    888  1.1  mrg       base_pointer = OBJ_TYPE_REF_OBJECT (ref);
    889  1.1  mrg     }
    890  1.1  mrg   else
    891  1.1  mrg     base_pointer = ref;
    892  1.1  mrg 
    893  1.1  mrg   /* Set up basic info in case we find nothing interesting in the analysis.  */
    894  1.1  mrg   clear_speculation ();
    895  1.1  mrg   clear_outer_type (otr_type);
    896  1.1  mrg   invalid = false;
    897  1.1  mrg 
    898  1.1  mrg   /* Walk SSA for outer object.  */
    899  1.1  mrg   while (true)
    900  1.1  mrg     {
    901  1.1  mrg       base_pointer = walk_ssa_copies (base_pointer, &visited);
    902  1.1  mrg       if (TREE_CODE (base_pointer) == ADDR_EXPR)
    903  1.1  mrg 	{
    904  1.1  mrg 	  HOST_WIDE_INT offset2, size;
    905  1.1  mrg 	  bool reverse;
    906  1.1  mrg 	  tree base
    907  1.1  mrg 	    = get_ref_base_and_extent_hwi (TREE_OPERAND (base_pointer, 0),
    908  1.1  mrg 					   &offset2, &size, &reverse);
    909  1.1  mrg 	  if (!base)
    910  1.1  mrg 	    break;
    911  1.1  mrg 
    912  1.1  mrg 	  combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)),
    913  1.1  mrg 				    offset + offset2,
    914  1.1  mrg 				    true,
    915  1.1  mrg 				    NULL /* Do not change outer type.  */);
    916  1.1  mrg 
    917  1.1  mrg 	  /* If this is a varying address, punt.  */
    918  1.1  mrg 	  if (TREE_CODE (base) == MEM_REF || DECL_P (base))
    919  1.1  mrg 	    {
    920  1.1  mrg 	      /* We found dereference of a pointer.  Type of the pointer
    921  1.1  mrg 		 and MEM_REF is meaningless, but we can look further.  */
    922  1.1  mrg 	      offset_int mem_offset;
    923  1.1  mrg 	      if (TREE_CODE (base) == MEM_REF
    924  1.1  mrg 		  && mem_ref_offset (base).is_constant (&mem_offset))
    925  1.1  mrg 		{
    926  1.1  mrg 		  offset_int o = mem_offset * BITS_PER_UNIT;
    927  1.1  mrg 		  o += offset;
    928  1.1  mrg 		  o += offset2;
    929  1.1  mrg 		  if (!wi::fits_shwi_p (o))
    930  1.1  mrg 		    break;
    931  1.1  mrg 		  base_pointer = TREE_OPERAND (base, 0);
    932  1.1  mrg 		  offset = o.to_shwi ();
    933  1.1  mrg 		  outer_type = NULL;
    934  1.1  mrg 		}
    935  1.1  mrg 	      /* We found base object.  In this case the outer_type
    936  1.1  mrg 		 is known.  */
    937  1.1  mrg 	      else if (DECL_P (base))
    938  1.1  mrg 		{
    939  1.1  mrg 		  if (visited)
    940  1.1  mrg 		    delete (visited);
    941  1.1  mrg 		  /* Only type inconsistent programs can have otr_type that is
    942  1.1  mrg 		     not part of outer type.  */
    943  1.1  mrg 		  if (otr_type
    944  1.1  mrg 		      && !contains_type_p (TREE_TYPE (base),
    945  1.1  mrg 					   offset + offset2, otr_type))
    946  1.1  mrg 		    {
    947  1.1  mrg 		      invalid = true;
    948  1.1  mrg 		      if (instance)
    949  1.1  mrg 			*instance = base_pointer;
    950  1.1  mrg 		      return;
    951  1.1  mrg 		    }
    952  1.1  mrg 		  set_by_decl (base, offset + offset2);
    953  1.1  mrg 		  if (outer_type && maybe_in_construction && stmt)
    954  1.1  mrg 		    maybe_in_construction
    955  1.1  mrg 		     = decl_maybe_in_construction_p (base,
    956  1.1  mrg 						     outer_type,
    957  1.1  mrg 						     stmt,
    958  1.1  mrg 						     fndecl);
    959  1.1  mrg 		  if (instance)
    960  1.1  mrg 		    *instance = base;
    961  1.1  mrg 		  return;
    962  1.1  mrg 		}
    963  1.1  mrg 	      else
    964  1.1  mrg 		break;
    965  1.1  mrg 	    }
    966  1.1  mrg 	  else
    967  1.1  mrg 	    break;
    968  1.1  mrg 	}
    969  1.1  mrg       else if (TREE_CODE (base_pointer) == POINTER_PLUS_EXPR
    970  1.1  mrg 	       && TREE_CODE (TREE_OPERAND (base_pointer, 1)) == INTEGER_CST)
    971  1.1  mrg 	{
    972  1.1  mrg 	  offset_int o
    973  1.1  mrg 	    = offset_int::from (wi::to_wide (TREE_OPERAND (base_pointer, 1)),
    974  1.1  mrg 				SIGNED);
    975  1.1  mrg 	  o *= BITS_PER_UNIT;
    976  1.1  mrg 	  o += offset;
    977  1.1  mrg 	  if (!wi::fits_shwi_p (o))
    978  1.1  mrg 	    break;
    979  1.1  mrg 	  offset = o.to_shwi ();
    980  1.1  mrg 	  base_pointer = TREE_OPERAND (base_pointer, 0);
    981  1.1  mrg 	}
    982  1.1  mrg       else
    983  1.1  mrg 	break;
    984  1.1  mrg     }
    985  1.1  mrg 
    986  1.1  mrg   if (visited)
    987  1.1  mrg     delete (visited);
    988  1.1  mrg 
    989  1.1  mrg   /* Try to determine type of the outer object.  */
    990  1.1  mrg   if (TREE_CODE (base_pointer) == SSA_NAME
    991  1.1  mrg       && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
    992  1.1  mrg       && TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL)
    993  1.1  mrg     {
    994  1.1  mrg       /* See if parameter is THIS pointer of a method.  */
    995  1.1  mrg       if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE
    996  1.1  mrg 	  && SSA_NAME_VAR (base_pointer) == DECL_ARGUMENTS (fndecl))
    997  1.1  mrg 	{
    998  1.1  mrg 	  outer_type
    999  1.1  mrg 	     = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
   1000  1.1  mrg 	  cgraph_node *node = cgraph_node::get (current_function_decl);
   1001  1.1  mrg 	  gcc_assert (TREE_CODE (outer_type) == RECORD_TYPE
   1002  1.1  mrg 		      || TREE_CODE (outer_type) == UNION_TYPE);
   1003  1.1  mrg 
   1004  1.1  mrg 	  /* Handle the case we inlined into a thunk.  In this case
   1005  1.1  mrg 	     thunk has THIS pointer of type bar, but it really receives
   1006  1.1  mrg 	     address to its base type foo which sits in bar at
   1007  1.1  mrg 	     0-thunk.fixed_offset.  It starts with code that adds
   1008  1.1  mrg 	     think.fixed_offset to the pointer to compensate for this.
   1009  1.1  mrg 
   1010  1.1  mrg 	     Because we walked all the way to the beginning of thunk, we now
   1011  1.1  mrg 	     see pointer &bar-thunk.fixed_offset and need to compensate
   1012  1.1  mrg 	     for it.  */
   1013  1.1  mrg 	  thunk_info *info = thunk_info::get (node);
   1014  1.1  mrg 	  if (info && info->fixed_offset)
   1015  1.1  mrg 	    offset -= info->fixed_offset * BITS_PER_UNIT;
   1016  1.1  mrg 
   1017  1.1  mrg 	  /* Dynamic casting has possibly upcasted the type
   1018  1.1  mrg 	     in the hierarchy.  In this case outer type is less
   1019  1.1  mrg 	     informative than inner type and we should forget
   1020  1.1  mrg 	     about it.  */
   1021  1.1  mrg 	  if ((otr_type
   1022  1.1  mrg 	       && !contains_type_p (outer_type, offset,
   1023  1.1  mrg 				    otr_type))
   1024  1.1  mrg 	      || !contains_polymorphic_type_p (outer_type)
   1025  1.1  mrg 	      /* If we compile thunk with virtual offset, the THIS pointer
   1026  1.1  mrg 		 is adjusted by unknown value.  We can't thus use outer info
   1027  1.1  mrg 		 at all.  */
   1028  1.1  mrg 	      || (info && info->virtual_offset_p))
   1029  1.1  mrg 	    {
   1030  1.1  mrg 	      outer_type = NULL;
   1031  1.1  mrg 	      if (instance)
   1032  1.1  mrg 		*instance = base_pointer;
   1033  1.1  mrg 	      return;
   1034  1.1  mrg 	    }
   1035  1.1  mrg 
   1036  1.1  mrg 	  dynamic = true;
   1037  1.1  mrg 
   1038  1.1  mrg 	  /* If the function is constructor or destructor, then
   1039  1.1  mrg 	     the type is possibly in construction, but we know
   1040  1.1  mrg 	     it is not derived type.  */
   1041  1.1  mrg 	  if (DECL_CXX_CONSTRUCTOR_P (fndecl)
   1042  1.1  mrg 	      || DECL_CXX_DESTRUCTOR_P (fndecl))
   1043  1.1  mrg 	    {
   1044  1.1  mrg 	      maybe_in_construction = true;
   1045  1.1  mrg 	      maybe_derived_type = false;
   1046  1.1  mrg 	    }
   1047  1.1  mrg 	  else
   1048  1.1  mrg 	    {
   1049  1.1  mrg 	      maybe_derived_type = true;
   1050  1.1  mrg 	      maybe_in_construction = false;
   1051  1.1  mrg 	    }
   1052  1.1  mrg 	  if (instance)
   1053  1.1  mrg 	    {
   1054  1.1  mrg 	      thunk_info *info = thunk_info::get (node);
   1055  1.1  mrg 	      /* If method is expanded thunk, we need to apply thunk offset
   1056  1.1  mrg 		 to instance pointer.  */
   1057  1.1  mrg 	      if (info && (info->virtual_offset_p || info->fixed_offset))
   1058  1.1  mrg 		*instance = NULL;
   1059  1.1  mrg 	      else
   1060  1.1  mrg 	        *instance = base_pointer;
   1061  1.1  mrg 	    }
   1062  1.1  mrg 	  return;
   1063  1.1  mrg 	}
   1064  1.1  mrg       /* Non-PODs passed by value are really passed by invisible
   1065  1.1  mrg 	 reference.  In this case we also know the type of the
   1066  1.1  mrg 	 object.  */
   1067  1.1  mrg       if (DECL_BY_REFERENCE (SSA_NAME_VAR (base_pointer)))
   1068  1.1  mrg 	{
   1069  1.1  mrg 	  outer_type
   1070  1.1  mrg 	     = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
   1071  1.1  mrg 	  /* Only type inconsistent programs can have otr_type that is
   1072  1.1  mrg 	     not part of outer type.  */
   1073  1.1  mrg 	  if (otr_type && !contains_type_p (outer_type, offset,
   1074  1.1  mrg 					    otr_type))
   1075  1.1  mrg 	    {
   1076  1.1  mrg 	      invalid = true;
   1077  1.1  mrg 	      if (instance)
   1078  1.1  mrg 		*instance = base_pointer;
   1079  1.1  mrg 	      return;
   1080  1.1  mrg 	    }
   1081  1.1  mrg 	  /* Non-polymorphic types have no interest for us.  */
   1082  1.1  mrg 	  else if (!otr_type && !contains_polymorphic_type_p (outer_type))
   1083  1.1  mrg 	    {
   1084  1.1  mrg 	      outer_type = NULL;
   1085  1.1  mrg 	      if (instance)
   1086  1.1  mrg 		*instance = base_pointer;
   1087  1.1  mrg 	      return;
   1088  1.1  mrg 	    }
   1089  1.1  mrg 	  maybe_derived_type = false;
   1090  1.1  mrg 	  maybe_in_construction = false;
   1091  1.1  mrg 	  if (instance)
   1092  1.1  mrg 	    *instance = base_pointer;
   1093  1.1  mrg 	  return;
   1094  1.1  mrg 	}
   1095  1.1  mrg     }
   1096  1.1  mrg 
   1097  1.1  mrg   tree base_type = TREE_TYPE (base_pointer);
   1098  1.1  mrg 
   1099  1.1  mrg   if (TREE_CODE (base_pointer) == SSA_NAME
   1100  1.1  mrg       && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
   1101  1.1  mrg       && !(TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL
   1102  1.1  mrg 	   || TREE_CODE (SSA_NAME_VAR (base_pointer)) == RESULT_DECL))
   1103  1.1  mrg     {
   1104  1.1  mrg       invalid = true;
   1105  1.1  mrg       if (instance)
   1106  1.1  mrg 	*instance = base_pointer;
   1107  1.1  mrg       return;
   1108  1.1  mrg     }
   1109  1.1  mrg   if (TREE_CODE (base_pointer) == SSA_NAME
   1110  1.1  mrg       && SSA_NAME_DEF_STMT (base_pointer)
   1111  1.1  mrg       && gimple_assign_single_p (SSA_NAME_DEF_STMT (base_pointer)))
   1112  1.1  mrg     base_type = TREE_TYPE (gimple_assign_rhs1
   1113  1.1  mrg 			    (SSA_NAME_DEF_STMT (base_pointer)));
   1114  1.1  mrg 
   1115  1.1  mrg   if (base_type && POINTER_TYPE_P (base_type))
   1116  1.1  mrg     combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base_type)),
   1117  1.1  mrg 			      offset,
   1118  1.1  mrg 			      true, NULL /* Do not change type here */);
   1119  1.1  mrg   /* TODO: There are multiple ways to derive a type.  For instance
   1120  1.1  mrg      if BASE_POINTER is passed to an constructor call prior our reference.
   1121  1.1  mrg      We do not make this type of flow sensitive analysis yet.  */
   1122  1.1  mrg   if (instance)
   1123  1.1  mrg     *instance = base_pointer;
   1124  1.1  mrg   return;
   1125  1.1  mrg }
   1126  1.1  mrg 
   1127  1.1  mrg /* Structure to be passed in between detect_type_change and
   1128  1.1  mrg    check_stmt_for_type_change.  */
   1129  1.1  mrg 
   1130  1.1  mrg struct type_change_info
   1131  1.1  mrg {
   1132  1.1  mrg   /* Offset into the object where there is the virtual method pointer we are
   1133  1.1  mrg      looking for.  */
   1134  1.1  mrg   HOST_WIDE_INT offset;
   1135  1.1  mrg   /* The declaration or SSA_NAME pointer of the base that we are checking for
   1136  1.1  mrg      type change.  */
   1137  1.1  mrg   tree instance;
   1138  1.1  mrg   /* The reference to virtual table pointer used.  */
   1139  1.1  mrg   tree vtbl_ptr_ref;
   1140  1.1  mrg   tree otr_type;
   1141  1.1  mrg   /* If we actually can tell the type that the object has changed to, it is
   1142  1.1  mrg      stored in this field.  Otherwise it remains NULL_TREE.  */
   1143  1.1  mrg   tree known_current_type;
   1144  1.1  mrg   HOST_WIDE_INT known_current_offset;
   1145  1.1  mrg 
   1146  1.1  mrg   /* Set to nonzero if we possibly missed some dynamic type changes and we
   1147  1.1  mrg      should consider the set to be speculative.  */
   1148  1.1  mrg   unsigned speculative;
   1149  1.1  mrg 
   1150  1.1  mrg   /* Set to true if dynamic type change has been detected.  */
   1151  1.1  mrg   bool type_maybe_changed;
   1152  1.1  mrg   /* Set to true if multiple types have been encountered.  known_current_type
   1153  1.1  mrg      must be disregarded in that case.  */
   1154  1.1  mrg   bool multiple_types_encountered;
   1155  1.1  mrg   bool seen_unanalyzed_store;
   1156  1.1  mrg };
   1157  1.1  mrg 
   1158  1.1  mrg /* Return true if STMT is not call and can modify a virtual method table pointer.
   1159  1.1  mrg    We take advantage of fact that vtable stores must appear within constructor
   1160  1.1  mrg    and destructor functions.  */
   1161  1.1  mrg 
   1162  1.1  mrg static bool
   1163  1.1  mrg noncall_stmt_may_be_vtbl_ptr_store (gimple *stmt)
   1164  1.1  mrg {
   1165  1.1  mrg   if (is_gimple_assign (stmt))
   1166  1.1  mrg     {
   1167  1.1  mrg       tree lhs = gimple_assign_lhs (stmt);
   1168  1.1  mrg 
   1169  1.1  mrg       if (gimple_clobber_p (stmt))
   1170  1.1  mrg 	return false;
   1171  1.1  mrg       if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
   1172  1.1  mrg 	{
   1173  1.1  mrg 	  if (flag_strict_aliasing
   1174  1.1  mrg 	      && !POINTER_TYPE_P (TREE_TYPE (lhs)))
   1175  1.1  mrg 	    return false;
   1176  1.1  mrg 
   1177  1.1  mrg 	  if (TREE_CODE (lhs) == COMPONENT_REF
   1178  1.1  mrg 	      && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
   1179  1.1  mrg 	    return false;
   1180  1.1  mrg 	  /* In the future we might want to use get_ref_base_and_extent to find
   1181  1.1  mrg 	     if there is a field corresponding to the offset and if so, proceed
   1182  1.1  mrg 	     almost like if it was a component ref.  */
   1183  1.1  mrg 	}
   1184  1.1  mrg     }
   1185  1.1  mrg 
   1186  1.1  mrg   /* Code unification may mess with inline stacks.  */
   1187  1.1  mrg   if (cfun->after_inlining)
   1188  1.1  mrg     return true;
   1189  1.1  mrg 
   1190  1.1  mrg   /* Walk the inline stack and watch out for ctors/dtors.
   1191  1.1  mrg      TODO: Maybe we can require the store to appear in toplevel
   1192  1.1  mrg      block of CTOR/DTOR.  */
   1193  1.1  mrg   for (tree block = gimple_block (stmt); block && TREE_CODE (block) == BLOCK;
   1194  1.1  mrg        block = BLOCK_SUPERCONTEXT (block))
   1195  1.1  mrg     if (BLOCK_ABSTRACT_ORIGIN (block)
   1196  1.1  mrg 	&& TREE_CODE (block_ultimate_origin (block)) == FUNCTION_DECL)
   1197  1.1  mrg       return inlined_polymorphic_ctor_dtor_block_p (block, false);
   1198  1.1  mrg   return (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
   1199  1.1  mrg 	  && (DECL_CXX_CONSTRUCTOR_P (current_function_decl)
   1200  1.1  mrg 	      || DECL_CXX_DESTRUCTOR_P (current_function_decl)));
   1201  1.1  mrg }
   1202  1.1  mrg 
   1203  1.1  mrg /* If STMT can be proved to be an assignment to the virtual method table
   1204  1.1  mrg    pointer of ANALYZED_OBJ and the type associated with the new table
   1205  1.1  mrg    identified, return the type.  Otherwise return NULL_TREE if type changes
   1206  1.1  mrg    in unknown way or ERROR_MARK_NODE if type is unchanged.  */
   1207  1.1  mrg 
   1208  1.1  mrg static tree
   1209  1.1  mrg extr_type_from_vtbl_ptr_store (gimple *stmt, struct type_change_info *tci,
   1210  1.1  mrg 			       HOST_WIDE_INT *type_offset)
   1211  1.1  mrg {
   1212  1.1  mrg   poly_int64 offset, size, max_size;
   1213  1.1  mrg   tree lhs, rhs, base;
   1214  1.1  mrg   bool reverse;
   1215  1.1  mrg 
   1216  1.1  mrg   if (!gimple_assign_single_p (stmt))
   1217  1.1  mrg     return NULL_TREE;
   1218  1.1  mrg 
   1219  1.1  mrg   lhs = gimple_assign_lhs (stmt);
   1220  1.1  mrg   rhs = gimple_assign_rhs1 (stmt);
   1221  1.1  mrg   if (TREE_CODE (lhs) != COMPONENT_REF
   1222  1.1  mrg       || !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
   1223  1.1  mrg      {
   1224  1.1  mrg 	if (dump_file)
   1225  1.1  mrg 	  fprintf (dump_file, "  LHS is not virtual table.\n");
   1226  1.1  mrg 	return NULL_TREE;
   1227  1.1  mrg      }
   1228  1.1  mrg 
   1229  1.1  mrg   if (tci->vtbl_ptr_ref && operand_equal_p (lhs, tci->vtbl_ptr_ref, 0))
   1230  1.1  mrg     ;
   1231  1.1  mrg   else
   1232  1.1  mrg     {
   1233  1.1  mrg       base = get_ref_base_and_extent (lhs, &offset, &size, &max_size, &reverse);
   1234  1.1  mrg       if (DECL_P (tci->instance))
   1235  1.1  mrg 	{
   1236  1.1  mrg 	  if (base != tci->instance)
   1237  1.1  mrg 	    {
   1238  1.1  mrg 	      if (dump_file)
   1239  1.1  mrg 		{
   1240  1.1  mrg 		  fprintf (dump_file, "    base:");
   1241  1.1  mrg 		  print_generic_expr (dump_file, base, TDF_SLIM);
   1242  1.1  mrg 		  fprintf (dump_file, " does not match instance:");
   1243  1.1  mrg 		  print_generic_expr (dump_file, tci->instance, TDF_SLIM);
   1244  1.1  mrg 		  fprintf (dump_file, "\n");
   1245  1.1  mrg 		}
   1246  1.1  mrg 	      return NULL_TREE;
   1247  1.1  mrg 	    }
   1248  1.1  mrg 	}
   1249  1.1  mrg       else if (TREE_CODE (base) == MEM_REF)
   1250  1.1  mrg 	{
   1251  1.1  mrg 	  if (!operand_equal_p (tci->instance, TREE_OPERAND (base, 0), 0))
   1252  1.1  mrg 	    {
   1253  1.1  mrg 	      if (dump_file)
   1254  1.1  mrg 		{
   1255  1.1  mrg 		  fprintf (dump_file, "    base mem ref:");
   1256  1.1  mrg 		  print_generic_expr (dump_file, base, TDF_SLIM);
   1257  1.1  mrg 		  fprintf (dump_file, " does not match instance:");
   1258  1.1  mrg 		  print_generic_expr (dump_file, tci->instance, TDF_SLIM);
   1259  1.1  mrg 		  fprintf (dump_file, "\n");
   1260  1.1  mrg 		}
   1261  1.1  mrg 	      return NULL_TREE;
   1262  1.1  mrg 	    }
   1263  1.1  mrg 	  if (!integer_zerop (TREE_OPERAND (base, 1)))
   1264  1.1  mrg 	    {
   1265  1.1  mrg 	      if (!tree_fits_shwi_p (TREE_OPERAND (base, 1)))
   1266  1.1  mrg 		{
   1267  1.1  mrg 		  if (dump_file)
   1268  1.1  mrg 		    {
   1269  1.1  mrg 		      fprintf (dump_file, "    base mem ref:");
   1270  1.1  mrg 		      print_generic_expr (dump_file, base, TDF_SLIM);
   1271  1.1  mrg 		      fprintf (dump_file, " has non-representable offset:");
   1272  1.1  mrg 		      print_generic_expr (dump_file, tci->instance, TDF_SLIM);
   1273  1.1  mrg 		      fprintf (dump_file, "\n");
   1274  1.1  mrg 		    }
   1275  1.1  mrg 		  return NULL_TREE;
   1276  1.1  mrg 		}
   1277  1.1  mrg 	      else
   1278  1.1  mrg 	        offset += tree_to_shwi (TREE_OPERAND (base, 1)) * BITS_PER_UNIT;
   1279  1.1  mrg 	    }
   1280  1.1  mrg 	}
   1281  1.1  mrg       else if (!operand_equal_p (tci->instance, base, 0)
   1282  1.1  mrg 	       || tci->offset)
   1283  1.1  mrg 	{
   1284  1.1  mrg 	  if (dump_file)
   1285  1.1  mrg 	    {
   1286  1.1  mrg 	      fprintf (dump_file, "    base:");
   1287  1.1  mrg 	      print_generic_expr (dump_file, base, TDF_SLIM);
   1288  1.1  mrg 	      fprintf (dump_file, " does not match instance:");
   1289  1.1  mrg 	      print_generic_expr (dump_file, tci->instance, TDF_SLIM);
   1290  1.1  mrg 	      fprintf (dump_file, " with offset %i\n", (int)tci->offset);
   1291  1.1  mrg 	    }
   1292  1.1  mrg 	  return tci->offset > POINTER_SIZE ? error_mark_node : NULL_TREE;
   1293  1.1  mrg 	}
   1294  1.1  mrg       if (maybe_ne (offset, tci->offset)
   1295  1.1  mrg 	  || maybe_ne (size, POINTER_SIZE)
   1296  1.1  mrg 	  || maybe_ne (max_size, POINTER_SIZE))
   1297  1.1  mrg 	{
   1298  1.1  mrg 	  if (dump_file)
   1299  1.1  mrg 	    {
   1300  1.1  mrg 	      fprintf (dump_file, "    wrong offset ");
   1301  1.1  mrg 	      print_dec (offset, dump_file);
   1302  1.1  mrg 	      fprintf (dump_file, "!=%i or size ", (int) tci->offset);
   1303  1.1  mrg 	      print_dec (size, dump_file);
   1304  1.1  mrg 	      fprintf (dump_file, "\n");
   1305  1.1  mrg 	    }
   1306  1.1  mrg 	  return (known_le (offset + POINTER_SIZE, tci->offset)
   1307  1.1  mrg 		  || (known_size_p (max_size)
   1308  1.1  mrg 		      && known_gt (tci->offset + POINTER_SIZE,
   1309  1.1  mrg 				   offset + max_size))
   1310  1.1  mrg 		  ? error_mark_node : NULL);
   1311  1.1  mrg 	}
   1312  1.1  mrg     }
   1313  1.1  mrg 
   1314  1.1  mrg   tree vtable;
   1315  1.1  mrg   unsigned HOST_WIDE_INT offset2;
   1316  1.1  mrg 
   1317  1.1  mrg   if (!vtable_pointer_value_to_vtable (rhs, &vtable, &offset2))
   1318  1.1  mrg     {
   1319  1.1  mrg       if (dump_file)
   1320  1.1  mrg 	fprintf (dump_file, "    Failed to lookup binfo\n");
   1321  1.1  mrg       return NULL;
   1322  1.1  mrg     }
   1323  1.1  mrg 
   1324  1.1  mrg   tree binfo = subbinfo_with_vtable_at_offset (TYPE_BINFO (DECL_CONTEXT (vtable)),
   1325  1.1  mrg 					       offset2, vtable);
   1326  1.1  mrg   if (!binfo)
   1327  1.1  mrg     {
   1328  1.1  mrg       if (dump_file)
   1329  1.1  mrg 	fprintf (dump_file, "    Construction vtable used\n");
   1330  1.1  mrg       /* FIXME: We should support construction contexts.  */
   1331  1.1  mrg       return NULL;
   1332  1.1  mrg     }
   1333  1.1  mrg 
   1334  1.1  mrg   *type_offset = tree_to_shwi (BINFO_OFFSET (binfo)) * BITS_PER_UNIT;
   1335  1.1  mrg   return DECL_CONTEXT (vtable);
   1336  1.1  mrg }
   1337  1.1  mrg 
   1338  1.1  mrg /* Record dynamic type change of TCI to TYPE.  */
   1339  1.1  mrg 
   1340  1.1  mrg static void
   1341  1.1  mrg record_known_type (struct type_change_info *tci, tree type, HOST_WIDE_INT offset)
   1342  1.1  mrg {
   1343  1.1  mrg   if (dump_file)
   1344  1.1  mrg     {
   1345  1.1  mrg       if (type)
   1346  1.1  mrg 	{
   1347  1.1  mrg           fprintf (dump_file, "  Recording type: ");
   1348  1.1  mrg 	  print_generic_expr (dump_file, type, TDF_SLIM);
   1349  1.1  mrg           fprintf (dump_file, " at offset %i\n", (int)offset);
   1350  1.1  mrg 	}
   1351  1.1  mrg      else
   1352  1.1  mrg        fprintf (dump_file, "  Recording unknown type\n");
   1353  1.1  mrg     }
   1354  1.1  mrg 
   1355  1.1  mrg   /* If we found a constructor of type that is not polymorphic or
   1356  1.1  mrg      that may contain the type in question as a field (not as base),
   1357  1.1  mrg      restrict to the inner class first to make type matching bellow
   1358  1.1  mrg      happier.  */
   1359  1.1  mrg   if (type
   1360  1.1  mrg       && (offset
   1361  1.1  mrg           || (TREE_CODE (type) != RECORD_TYPE
   1362  1.1  mrg 	      || !TYPE_BINFO (type)
   1363  1.1  mrg 	      || !polymorphic_type_binfo_p (TYPE_BINFO (type)))))
   1364  1.1  mrg     {
   1365  1.1  mrg       ipa_polymorphic_call_context context;
   1366  1.1  mrg 
   1367  1.1  mrg       context.offset = offset;
   1368  1.1  mrg       context.outer_type = type;
   1369  1.1  mrg       context.maybe_in_construction = false;
   1370  1.1  mrg       context.maybe_derived_type = false;
   1371  1.1  mrg       context.dynamic = true;
   1372  1.1  mrg       /* If we failed to find the inner type, we know that the call
   1373  1.1  mrg 	 would be undefined for type produced here.  */
   1374  1.1  mrg       if (!context.restrict_to_inner_class (tci->otr_type))
   1375  1.1  mrg 	{
   1376  1.1  mrg 	  if (dump_file)
   1377  1.1  mrg 	    fprintf (dump_file, "  Ignoring; does not contain otr_type\n");
   1378  1.1  mrg 	  return;
   1379  1.1  mrg 	}
   1380  1.1  mrg       /* Watch for case we reached an POD type and anticipate placement
   1381  1.1  mrg 	 new.  */
   1382  1.1  mrg       if (!context.maybe_derived_type)
   1383  1.1  mrg 	{
   1384  1.1  mrg           type = context.outer_type;
   1385  1.1  mrg           offset = context.offset;
   1386  1.1  mrg 	}
   1387  1.1  mrg     }
   1388  1.1  mrg   if (tci->type_maybe_changed
   1389  1.1  mrg       && (!types_same_for_odr (type, tci->known_current_type)
   1390  1.1  mrg 	  || offset != tci->known_current_offset))
   1391  1.1  mrg     tci->multiple_types_encountered = true;
   1392  1.1  mrg   tci->known_current_type = TYPE_MAIN_VARIANT (type);
   1393  1.1  mrg   tci->known_current_offset = offset;
   1394  1.1  mrg   tci->type_maybe_changed = true;
   1395  1.1  mrg }
   1396  1.1  mrg 
   1397  1.1  mrg 
   1398  1.1  mrg /* The maximum number of may-defs we visit when looking for a must-def
   1399  1.1  mrg    that changes the dynamic type in check_stmt_for_type_change.  Tuned
   1400  1.1  mrg    after the PR12392 testcase which unlimited spends 40% time within
   1401  1.1  mrg    these alias walks and 8% with the following limit.  */
   1402  1.1  mrg 
   1403  1.1  mrg static inline bool
   1404  1.1  mrg csftc_abort_walking_p (unsigned speculative)
   1405  1.1  mrg {
   1406  1.1  mrg   unsigned max = param_max_speculative_devirt_maydefs;
   1407  1.1  mrg   return speculative > max ? true : false;
   1408  1.1  mrg }
   1409  1.1  mrg 
   1410  1.1  mrg /* Callback of walk_aliased_vdefs and a helper function for
   1411  1.1  mrg    detect_type_change to check whether a particular statement may modify
   1412  1.1  mrg    the virtual table pointer, and if possible also determine the new type of
   1413  1.1  mrg    the (sub-)object.  It stores its result into DATA, which points to a
   1414  1.1  mrg    type_change_info structure.  */
   1415  1.1  mrg 
   1416  1.1  mrg static bool
   1417  1.1  mrg check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
   1418  1.1  mrg {
   1419  1.1  mrg   gimple *stmt = SSA_NAME_DEF_STMT (vdef);
   1420  1.1  mrg   struct type_change_info *tci = (struct type_change_info *) data;
   1421  1.1  mrg   tree fn;
   1422  1.1  mrg 
   1423  1.1  mrg   /* If we already gave up, just terminate the rest of walk.  */
   1424  1.1  mrg   if (tci->multiple_types_encountered)
   1425  1.1  mrg     return true;
   1426  1.1  mrg 
   1427  1.1  mrg   if (is_gimple_call (stmt))
   1428  1.1  mrg     {
   1429  1.1  mrg       if (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))
   1430  1.1  mrg 	return false;
   1431  1.1  mrg 
   1432  1.1  mrg       /* Check for a constructor call.  */
   1433  1.1  mrg       if ((fn = gimple_call_fndecl (stmt)) != NULL_TREE
   1434  1.1  mrg 	  && DECL_CXX_CONSTRUCTOR_P (fn)
   1435  1.1  mrg 	  && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
   1436  1.1  mrg 	  && gimple_call_num_args (stmt))
   1437  1.1  mrg       {
   1438  1.1  mrg 	tree op = walk_ssa_copies (gimple_call_arg (stmt, 0));
   1439  1.1  mrg 	tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
   1440  1.1  mrg 	HOST_WIDE_INT offset = 0;
   1441  1.1  mrg 	bool reverse;
   1442  1.1  mrg 
   1443  1.1  mrg 	if (dump_file)
   1444  1.1  mrg 	  {
   1445  1.1  mrg 	    fprintf (dump_file, "  Checking constructor call: ");
   1446  1.1  mrg 	    print_gimple_stmt (dump_file, stmt, 0);
   1447  1.1  mrg 	  }
   1448  1.1  mrg 
   1449  1.1  mrg 	/* See if THIS parameter seems like instance pointer.  */
   1450  1.1  mrg 	if (TREE_CODE (op) == ADDR_EXPR)
   1451  1.1  mrg 	  {
   1452  1.1  mrg 	    HOST_WIDE_INT size;
   1453  1.1  mrg 	    op = get_ref_base_and_extent_hwi (TREE_OPERAND (op, 0),
   1454  1.1  mrg 					      &offset, &size, &reverse);
   1455  1.1  mrg 	    if (!op)
   1456  1.1  mrg 	      {
   1457  1.1  mrg                 tci->speculative++;
   1458  1.1  mrg 	        return csftc_abort_walking_p (tci->speculative);
   1459  1.1  mrg 	      }
   1460  1.1  mrg 	    if (TREE_CODE (op) == MEM_REF)
   1461  1.1  mrg 	      {
   1462  1.1  mrg 		if (!tree_fits_shwi_p (TREE_OPERAND (op, 1)))
   1463  1.1  mrg 		  {
   1464  1.1  mrg                     tci->speculative++;
   1465  1.1  mrg 		    return csftc_abort_walking_p (tci->speculative);
   1466  1.1  mrg 		  }
   1467  1.1  mrg 		offset += tree_to_shwi (TREE_OPERAND (op, 1))
   1468  1.1  mrg 			  * BITS_PER_UNIT;
   1469  1.1  mrg 		op = TREE_OPERAND (op, 0);
   1470  1.1  mrg 	      }
   1471  1.1  mrg 	    else if (DECL_P (op))
   1472  1.1  mrg 	      ;
   1473  1.1  mrg 	    else
   1474  1.1  mrg 	      {
   1475  1.1  mrg                 tci->speculative++;
   1476  1.1  mrg 	        return csftc_abort_walking_p (tci->speculative);
   1477  1.1  mrg 	      }
   1478  1.1  mrg 	    op = walk_ssa_copies (op);
   1479  1.1  mrg 	  }
   1480  1.1  mrg 	if (operand_equal_p (op, tci->instance, 0)
   1481  1.1  mrg 	    && TYPE_SIZE (type)
   1482  1.1  mrg 	    && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   1483  1.1  mrg 	    && tree_fits_shwi_p (TYPE_SIZE (type))
   1484  1.1  mrg 	    && tree_to_shwi (TYPE_SIZE (type)) + offset > tci->offset
   1485  1.1  mrg 	    /* Some inlined constructors may look as follows:
   1486  1.1  mrg 		  _3 = operator new (16);
   1487  1.1  mrg 		  MEM[(struct  &)_3] ={v} {CLOBBER};
   1488  1.1  mrg 		  MEM[(struct CompositeClass *)_3]._vptr.CompositeClass
   1489  1.1  mrg 		    = &MEM[(void *)&_ZTV14CompositeClass + 16B];
   1490  1.1  mrg 		  _7 = &MEM[(struct CompositeClass *)_3].object;
   1491  1.1  mrg 		  EmptyClass::EmptyClass (_7);
   1492  1.1  mrg 
   1493  1.1  mrg 	       When determining dynamic type of _3 and because we stop at first
   1494  1.1  mrg 	       dynamic type found, we would stop on EmptyClass::EmptyClass (_7).
   1495  1.1  mrg 	       In this case the emptyclass is not even polymorphic and we miss
   1496  1.1  mrg 	       it is contained in an outer type that is polymorphic.  */
   1497  1.1  mrg 
   1498  1.1  mrg 	    && (tci->offset == offset || contains_polymorphic_type_p (type)))
   1499  1.1  mrg 	  {
   1500  1.1  mrg 	    record_known_type (tci, type, tci->offset - offset);
   1501  1.1  mrg 	    return true;
   1502  1.1  mrg 	  }
   1503  1.1  mrg       }
   1504  1.1  mrg      /* Calls may possibly change dynamic type by placement new. Assume
   1505  1.1  mrg         it will not happen, but make result speculative only.  */
   1506  1.1  mrg      if (dump_file)
   1507  1.1  mrg 	{
   1508  1.1  mrg           fprintf (dump_file, "  Function call may change dynamic type:");
   1509  1.1  mrg 	  print_gimple_stmt (dump_file, stmt, 0);
   1510  1.1  mrg 	}
   1511  1.1  mrg      tci->speculative++;
   1512  1.1  mrg      return csftc_abort_walking_p (tci->speculative);
   1513  1.1  mrg    }
   1514  1.1  mrg   /* Check for inlined virtual table store.  */
   1515  1.1  mrg   else if (noncall_stmt_may_be_vtbl_ptr_store (stmt))
   1516  1.1  mrg     {
   1517  1.1  mrg       tree type;
   1518  1.1  mrg       HOST_WIDE_INT offset = 0;
   1519  1.1  mrg       if (dump_file)
   1520  1.1  mrg 	{
   1521  1.1  mrg 	  fprintf (dump_file, "  Checking vtbl store: ");
   1522  1.1  mrg 	  print_gimple_stmt (dump_file, stmt, 0);
   1523  1.1  mrg 	}
   1524  1.1  mrg 
   1525  1.1  mrg       type = extr_type_from_vtbl_ptr_store (stmt, tci, &offset);
   1526  1.1  mrg       if (type == error_mark_node)
   1527  1.1  mrg 	return false;
   1528  1.1  mrg       gcc_assert (!type || TYPE_MAIN_VARIANT (type) == type);
   1529  1.1  mrg       if (!type)
   1530  1.1  mrg 	{
   1531  1.1  mrg 	  if (dump_file)
   1532  1.1  mrg 	    fprintf (dump_file, "  Unanalyzed store may change type.\n");
   1533  1.1  mrg 	  tci->seen_unanalyzed_store = true;
   1534  1.1  mrg 	  tci->speculative++;
   1535  1.1  mrg 	}
   1536  1.1  mrg       else
   1537  1.1  mrg         record_known_type (tci, type, offset);
   1538  1.1  mrg       return true;
   1539  1.1  mrg     }
   1540  1.1  mrg   else
   1541  1.1  mrg     return false;
   1542  1.1  mrg }
   1543  1.1  mrg 
   1544  1.1  mrg /* THIS is polymorphic call context obtained from get_polymorphic_context.
   1545  1.1  mrg    OTR_OBJECT is pointer to the instance returned by OBJ_TYPE_REF_OBJECT.
   1546  1.1  mrg    INSTANCE is pointer to the outer instance as returned by
   1547  1.1  mrg    get_polymorphic_context.  To avoid creation of temporary expressions,
   1548  1.1  mrg    INSTANCE may also be an declaration of get_polymorphic_context found the
   1549  1.1  mrg    value to be in static storage.
   1550  1.1  mrg 
   1551  1.1  mrg    If the type of instance is not fully determined
   1552  1.1  mrg    (either OUTER_TYPE is unknown or MAYBE_IN_CONSTRUCTION/INCLUDE_DERIVED_TYPES
   1553  1.1  mrg    is set), try to walk memory writes and find the actual construction of the
   1554  1.1  mrg    instance.
   1555  1.1  mrg 
   1556  1.1  mrg    Return true if memory is unchanged from function entry.
   1557  1.1  mrg 
   1558  1.1  mrg    We do not include this analysis in the context analysis itself, because
   1559  1.1  mrg    it needs memory SSA to be fully built and the walk may be expensive.
   1560  1.1  mrg    So it is not suitable for use withing fold_stmt and similar uses.
   1561  1.1  mrg 
   1562  1.1  mrg    AA_WALK_BUDGET_P, if not NULL, is how statements we should allow
   1563  1.1  mrg    walk_aliased_vdefs to examine.  The value should be decremented by the
   1564  1.1  mrg    number of statements we examined or set to zero if exhausted.  */
   1565  1.1  mrg 
   1566  1.1  mrg bool
   1567  1.1  mrg ipa_polymorphic_call_context::get_dynamic_type (tree instance,
   1568  1.1  mrg 						tree otr_object,
   1569  1.1  mrg 						tree otr_type,
   1570  1.1  mrg 						gimple *call,
   1571  1.1  mrg 						unsigned *aa_walk_budget_p)
   1572  1.1  mrg {
   1573  1.1  mrg   struct type_change_info tci;
   1574  1.1  mrg   ao_ref ao;
   1575  1.1  mrg   bool function_entry_reached = false;
   1576  1.1  mrg   tree instance_ref = NULL;
   1577  1.1  mrg   gimple *stmt = call;
   1578  1.1  mrg   /* Remember OFFSET before it is modified by restrict_to_inner_class.
   1579  1.1  mrg      This is because we do not update INSTANCE when walking inwards.  */
   1580  1.1  mrg   HOST_WIDE_INT instance_offset = offset;
   1581  1.1  mrg   tree instance_outer_type = outer_type;
   1582  1.1  mrg 
   1583  1.1  mrg   if (!instance)
   1584  1.1  mrg     return false;
   1585  1.1  mrg 
   1586  1.1  mrg   if (otr_type)
   1587  1.1  mrg     otr_type = TYPE_MAIN_VARIANT (otr_type);
   1588  1.1  mrg 
   1589  1.1  mrg   /* Walk into inner type. This may clear maybe_derived_type and save us
   1590  1.1  mrg      from useless work.  It also makes later comparisons with static type
   1591  1.1  mrg      easier.  */
   1592  1.1  mrg   if (outer_type && otr_type)
   1593  1.1  mrg     {
   1594  1.1  mrg       if (!restrict_to_inner_class (otr_type))
   1595  1.1  mrg         return false;
   1596  1.1  mrg     }
   1597  1.1  mrg 
   1598  1.1  mrg   if (!maybe_in_construction && !maybe_derived_type)
   1599  1.1  mrg     return false;
   1600  1.1  mrg 
   1601  1.1  mrg   /* If we are in fact not looking at any object or the instance is
   1602  1.1  mrg      some placement new into a random load, give up straight away.  */
   1603  1.1  mrg   if (TREE_CODE (instance) == MEM_REF)
   1604  1.1  mrg     return false;
   1605  1.1  mrg 
   1606  1.1  mrg   /* We need to obtain reference to virtual table pointer.  It is better
   1607  1.1  mrg      to look it up in the code rather than build our own.  This require bit
   1608  1.1  mrg      of pattern matching, but we end up verifying that what we found is
   1609  1.1  mrg      correct.
   1610  1.1  mrg 
   1611  1.1  mrg      What we pattern match is:
   1612  1.1  mrg 
   1613  1.1  mrg        tmp = instance->_vptr.A;   // vtbl ptr load
   1614  1.1  mrg        tmp2 = tmp[otr_token];	  // vtable lookup
   1615  1.1  mrg        OBJ_TYPE_REF(tmp2;instance->0) (instance);
   1616  1.1  mrg 
   1617  1.1  mrg      We want to start alias oracle walk from vtbl pointer load,
   1618  1.1  mrg      but we may not be able to identify it, for example, when PRE moved the
   1619  1.1  mrg      load around.  */
   1620  1.1  mrg 
   1621  1.1  mrg   if (gimple_code (call) == GIMPLE_CALL)
   1622  1.1  mrg     {
   1623  1.1  mrg       tree ref = gimple_call_fn (call);
   1624  1.1  mrg       bool reverse;
   1625  1.1  mrg 
   1626  1.1  mrg       if (TREE_CODE (ref) == OBJ_TYPE_REF)
   1627  1.1  mrg 	{
   1628  1.1  mrg 	  ref = OBJ_TYPE_REF_EXPR (ref);
   1629  1.1  mrg 	  ref = walk_ssa_copies (ref);
   1630  1.1  mrg 
   1631  1.1  mrg 	  /* If call target is already known, no need to do the expensive
   1632  1.1  mrg  	     memory walk.  */
   1633  1.1  mrg 	  if (is_gimple_min_invariant (ref))
   1634  1.1  mrg 	    return false;
   1635  1.1  mrg 
   1636  1.1  mrg 	  /* Check if definition looks like vtable lookup.  */
   1637  1.1  mrg 	  if (TREE_CODE (ref) == SSA_NAME
   1638  1.1  mrg 	      && !SSA_NAME_IS_DEFAULT_DEF (ref)
   1639  1.1  mrg 	      && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref))
   1640  1.1  mrg 	      && TREE_CODE (gimple_assign_rhs1
   1641  1.1  mrg 			     (SSA_NAME_DEF_STMT (ref))) == MEM_REF)
   1642  1.1  mrg 	    {
   1643  1.1  mrg 	      ref = get_base_address
   1644  1.1  mrg 		     (TREE_OPERAND (gimple_assign_rhs1
   1645  1.1  mrg 				     (SSA_NAME_DEF_STMT (ref)), 0));
   1646  1.1  mrg 	      ref = walk_ssa_copies (ref);
   1647  1.1  mrg 	      /* Find base address of the lookup and see if it looks like
   1648  1.1  mrg 		 vptr load.  */
   1649  1.1  mrg 	      if (TREE_CODE (ref) == SSA_NAME
   1650  1.1  mrg 		  && !SSA_NAME_IS_DEFAULT_DEF (ref)
   1651  1.1  mrg 		  && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref)))
   1652  1.1  mrg 		{
   1653  1.1  mrg 		  HOST_WIDE_INT offset2, size;
   1654  1.1  mrg 		  tree ref_exp = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (ref));
   1655  1.1  mrg 		  tree base_ref
   1656  1.1  mrg 		    = get_ref_base_and_extent_hwi (ref_exp, &offset2,
   1657  1.1  mrg 						   &size, &reverse);
   1658  1.1  mrg 
   1659  1.1  mrg 		  /* Finally verify that what we found looks like read from
   1660  1.1  mrg 		     OTR_OBJECT or from INSTANCE with offset OFFSET.  */
   1661  1.1  mrg 		  if (base_ref
   1662  1.1  mrg 		      && ((TREE_CODE (base_ref) == MEM_REF
   1663  1.1  mrg 		           && ((offset2 == instance_offset
   1664  1.1  mrg 		                && TREE_OPERAND (base_ref, 0) == instance)
   1665  1.1  mrg 			       || (!offset2
   1666  1.1  mrg 				   && TREE_OPERAND (base_ref, 0)
   1667  1.1  mrg 				      == otr_object)))
   1668  1.1  mrg 			  || (DECL_P (instance) && base_ref == instance
   1669  1.1  mrg 			      && offset2 == instance_offset)))
   1670  1.1  mrg 		    {
   1671  1.1  mrg 		      stmt = SSA_NAME_DEF_STMT (ref);
   1672  1.1  mrg 		      instance_ref = ref_exp;
   1673  1.1  mrg 		    }
   1674  1.1  mrg 		}
   1675  1.1  mrg 	    }
   1676  1.1  mrg 	}
   1677  1.1  mrg     }
   1678  1.1  mrg 
   1679  1.1  mrg   /* If we failed to look up the reference in code, build our own.  */
   1680  1.1  mrg   if (!instance_ref)
   1681  1.1  mrg     {
   1682  1.1  mrg       /* If the statement in question does not use memory, we can't tell
   1683  1.1  mrg 	 anything.  */
   1684  1.1  mrg       if (!gimple_vuse (stmt))
   1685  1.1  mrg 	return false;
   1686  1.1  mrg       ao_ref_init_from_ptr_and_size (&ao, otr_object, NULL);
   1687  1.1  mrg     }
   1688  1.1  mrg   else
   1689  1.1  mrg   /* Otherwise use the real reference.  */
   1690  1.1  mrg     ao_ref_init (&ao, instance_ref);
   1691  1.1  mrg 
   1692  1.1  mrg   /* We look for vtbl pointer read.  */
   1693  1.1  mrg   ao.size = POINTER_SIZE;
   1694  1.1  mrg   ao.max_size = ao.size;
   1695  1.1  mrg   /* We are looking for stores to vptr pointer within the instance of
   1696  1.1  mrg      outer type.
   1697  1.1  mrg      TODO: The vptr pointer type is globally known, we probably should
   1698  1.1  mrg      keep it and do that even when otr_type is unknown.  */
   1699  1.1  mrg   if (otr_type)
   1700  1.1  mrg     {
   1701  1.1  mrg       ao.base_alias_set
   1702  1.1  mrg 	= get_alias_set (outer_type ? outer_type : otr_type);
   1703  1.1  mrg       ao.ref_alias_set
   1704  1.1  mrg         = get_alias_set (TREE_TYPE (BINFO_VTABLE (TYPE_BINFO (otr_type))));
   1705  1.1  mrg     }
   1706  1.1  mrg 
   1707  1.1  mrg   if (dump_file)
   1708  1.1  mrg     {
   1709  1.1  mrg       fprintf (dump_file, "Determining dynamic type for call: ");
   1710  1.1  mrg       print_gimple_stmt (dump_file, call, 0);
   1711  1.1  mrg       fprintf (dump_file, "  Starting walk at: ");
   1712  1.1  mrg       print_gimple_stmt (dump_file, stmt, 0);
   1713  1.1  mrg       fprintf (dump_file, "  instance pointer: ");
   1714  1.1  mrg       print_generic_expr (dump_file, otr_object, TDF_SLIM);
   1715  1.1  mrg       fprintf (dump_file, "  Outer instance pointer: ");
   1716  1.1  mrg       print_generic_expr (dump_file, instance, TDF_SLIM);
   1717  1.1  mrg       fprintf (dump_file, " offset: %i (bits)", (int)instance_offset);
   1718  1.1  mrg       fprintf (dump_file, " vtbl reference: ");
   1719  1.1  mrg       print_generic_expr (dump_file, instance_ref, TDF_SLIM);
   1720  1.1  mrg       fprintf (dump_file, "\n");
   1721  1.1  mrg     }
   1722  1.1  mrg 
   1723  1.1  mrg   tci.offset = instance_offset;
   1724  1.1  mrg   tci.instance = instance;
   1725  1.1  mrg   tci.vtbl_ptr_ref = instance_ref;
   1726  1.1  mrg   tci.known_current_type = NULL_TREE;
   1727  1.1  mrg   tci.known_current_offset = 0;
   1728  1.1  mrg   tci.otr_type = otr_type;
   1729  1.1  mrg   tci.type_maybe_changed = false;
   1730  1.1  mrg   tci.multiple_types_encountered = false;
   1731  1.1  mrg   tci.speculative = 0;
   1732  1.1  mrg   tci.seen_unanalyzed_store = false;
   1733  1.1  mrg 
   1734  1.1  mrg   unsigned aa_walk_budget = 0;
   1735  1.1  mrg   if (aa_walk_budget_p)
   1736  1.1  mrg     aa_walk_budget = *aa_walk_budget_p + 1;
   1737  1.1  mrg 
   1738  1.1  mrg   int walked
   1739  1.1  mrg    = walk_aliased_vdefs (&ao, gimple_vuse (stmt), check_stmt_for_type_change,
   1740  1.1  mrg 			 &tci, NULL, &function_entry_reached, aa_walk_budget);
   1741  1.1  mrg 
   1742  1.1  mrg   /* If we did not find any type changing statements, we may still drop
   1743  1.1  mrg      maybe_in_construction flag if the context already have outer type.
   1744  1.1  mrg 
   1745  1.1  mrg      Here we make special assumptions about both constructors and
   1746  1.1  mrg      destructors which are all the functions that are allowed to alter the
   1747  1.1  mrg      VMT pointers.  It assumes that destructors begin with assignment into
   1748  1.1  mrg      all VMT pointers and that constructors essentially look in the
   1749  1.1  mrg      following way:
   1750  1.1  mrg 
   1751  1.1  mrg      1) The very first thing they do is that they call constructors of
   1752  1.1  mrg      ancestor sub-objects that have them.
   1753  1.1  mrg 
   1754  1.1  mrg      2) Then VMT pointers of this and all its ancestors is set to new
   1755  1.1  mrg      values corresponding to the type corresponding to the constructor.
   1756  1.1  mrg 
   1757  1.1  mrg      3) Only afterwards, other stuff such as constructor of member
   1758  1.1  mrg      sub-objects and the code written by the user is run.  Only this may
   1759  1.1  mrg      include calling virtual functions, directly or indirectly.
   1760  1.1  mrg 
   1761  1.1  mrg      4) placement new cannot be used to change type of non-POD statically
   1762  1.1  mrg      allocated variables.
   1763  1.1  mrg 
   1764  1.1  mrg      There is no way to call a constructor of an ancestor sub-object in any
   1765  1.1  mrg      other way.
   1766  1.1  mrg 
   1767  1.1  mrg      This means that we do not have to care whether constructors get the
   1768  1.1  mrg      correct type information because they will always change it (in fact,
   1769  1.1  mrg      if we define the type to be given by the VMT pointer, it is undefined).
   1770  1.1  mrg 
   1771  1.1  mrg      The most important fact to derive from the above is that if, for some
   1772  1.1  mrg      statement in the section 3, we try to detect whether the dynamic type
   1773  1.1  mrg      has changed, we can safely ignore all calls as we examine the function
   1774  1.1  mrg      body backwards until we reach statements in section 2 because these
   1775  1.1  mrg      calls cannot be ancestor constructors or destructors (if the input is
   1776  1.1  mrg      not bogus) and so do not change the dynamic type (this holds true only
   1777  1.1  mrg      for automatically allocated objects but at the moment we devirtualize
   1778  1.1  mrg      only these).  We then must detect that statements in section 2 change
   1779  1.1  mrg      the dynamic type and can try to derive the new type.  That is enough
   1780  1.1  mrg      and we can stop, we will never see the calls into constructors of
   1781  1.1  mrg      sub-objects in this code.
   1782  1.1  mrg 
   1783  1.1  mrg      Therefore if the static outer type was found (outer_type)
   1784  1.1  mrg      we can safely ignore tci.speculative that is set on calls and give up
   1785  1.1  mrg      only if there was dynamic type store that may affect given variable
   1786  1.1  mrg      (seen_unanalyzed_store)  */
   1787  1.1  mrg 
   1788  1.1  mrg   if (walked < 0)
   1789  1.1  mrg     {
   1790  1.1  mrg       if (dump_file)
   1791  1.1  mrg 	fprintf (dump_file, "  AA walk budget exhausted.\n");
   1792  1.1  mrg       *aa_walk_budget_p = 0;
   1793  1.1  mrg       return false;
   1794  1.1  mrg     }
   1795  1.1  mrg   else if (aa_walk_budget_p)
   1796  1.1  mrg     *aa_walk_budget_p -= walked;
   1797  1.1  mrg 
   1798  1.1  mrg   if (!tci.type_maybe_changed
   1799  1.1  mrg       || (outer_type
   1800  1.1  mrg 	  && !dynamic
   1801  1.1  mrg 	  && !tci.seen_unanalyzed_store
   1802  1.1  mrg 	  && !tci.multiple_types_encountered
   1803  1.1  mrg 	  && ((offset == tci.offset
   1804  1.1  mrg 	       && types_same_for_odr (tci.known_current_type,
   1805  1.1  mrg 				      outer_type))
   1806  1.1  mrg 	       || (instance_offset == offset
   1807  1.1  mrg 		   && types_same_for_odr (tci.known_current_type,
   1808  1.1  mrg 					  instance_outer_type)))))
   1809  1.1  mrg     {
   1810  1.1  mrg       if (!outer_type || tci.seen_unanalyzed_store)
   1811  1.1  mrg 	return false;
   1812  1.1  mrg       if (maybe_in_construction)
   1813  1.1  mrg         maybe_in_construction = false;
   1814  1.1  mrg       if (dump_file)
   1815  1.1  mrg 	fprintf (dump_file, "  No dynamic type change found.\n");
   1816  1.1  mrg       return true;
   1817  1.1  mrg     }
   1818  1.1  mrg 
   1819  1.1  mrg   if (tci.known_current_type
   1820  1.1  mrg       && !function_entry_reached
   1821  1.1  mrg       && !tci.multiple_types_encountered)
   1822  1.1  mrg     {
   1823  1.1  mrg       if (!tci.speculative)
   1824  1.1  mrg 	{
   1825  1.1  mrg 	  outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
   1826  1.1  mrg 	  offset = tci.known_current_offset;
   1827  1.1  mrg 	  dynamic = true;
   1828  1.1  mrg 	  maybe_in_construction = false;
   1829  1.1  mrg 	  maybe_derived_type = false;
   1830  1.1  mrg 	  if (dump_file)
   1831  1.1  mrg 	    fprintf (dump_file, "  Determined dynamic type.\n");
   1832  1.1  mrg 	}
   1833  1.1  mrg       else if (!speculative_outer_type
   1834  1.1  mrg 	       || speculative_maybe_derived_type)
   1835  1.1  mrg 	{
   1836  1.1  mrg 	  speculative_outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
   1837  1.1  mrg 	  speculative_offset = tci.known_current_offset;
   1838  1.1  mrg 	  speculative_maybe_derived_type = false;
   1839  1.1  mrg 	  if (dump_file)
   1840  1.1  mrg 	    fprintf (dump_file, "  Determined speculative dynamic type.\n");
   1841  1.1  mrg 	}
   1842  1.1  mrg     }
   1843  1.1  mrg   else if (dump_file)
   1844  1.1  mrg     {
   1845  1.1  mrg       fprintf (dump_file, "  Found multiple types%s%s\n",
   1846  1.1  mrg 	       function_entry_reached ? " (function entry reached)" : "",
   1847  1.1  mrg 	       function_entry_reached ? " (multiple types encountered)" : "");
   1848  1.1  mrg     }
   1849  1.1  mrg 
   1850  1.1  mrg   return false;
   1851  1.1  mrg }
   1852  1.1  mrg 
   1853  1.1  mrg /* See if speculation given by SPEC_OUTER_TYPE, SPEC_OFFSET and SPEC_MAYBE_DERIVED_TYPE
   1854  1.1  mrg    seems consistent (and useful) with what we already have in the non-speculative context.  */
   1855  1.1  mrg 
   1856  1.1  mrg bool
   1857  1.1  mrg ipa_polymorphic_call_context::speculation_consistent_p (tree spec_outer_type,
   1858  1.1  mrg 							HOST_WIDE_INT spec_offset,
   1859  1.1  mrg 							bool spec_maybe_derived_type,
   1860  1.1  mrg 							tree otr_type) const
   1861  1.1  mrg {
   1862  1.1  mrg   if (!flag_devirtualize_speculatively)
   1863  1.1  mrg     return false;
   1864  1.1  mrg 
   1865  1.1  mrg   /* Non-polymorphic types are useless for deriving likely polymorphic
   1866  1.1  mrg      call targets.  */
   1867  1.1  mrg   if (!spec_outer_type || !contains_polymorphic_type_p (spec_outer_type))
   1868  1.1  mrg     return false;
   1869  1.1  mrg 
   1870  1.1  mrg   /* If we know nothing, speculation is always good.  */
   1871  1.1  mrg   if (!outer_type)
   1872  1.1  mrg     return true;
   1873  1.1  mrg 
   1874  1.1  mrg   /* Speculation is only useful to avoid derived types.
   1875  1.1  mrg      This is not 100% true for placement new, where the outer context may
   1876  1.1  mrg      turn out to be useless, but ignore these for now.  */
   1877  1.1  mrg   if (!maybe_derived_type)
   1878  1.1  mrg     return false;
   1879  1.1  mrg 
   1880  1.1  mrg   /* If types agrees, speculation is consistent, but it makes sense only
   1881  1.1  mrg      when it says something new.  */
   1882  1.1  mrg   if (types_must_be_same_for_odr (spec_outer_type, outer_type))
   1883  1.1  mrg     return maybe_derived_type && !spec_maybe_derived_type;
   1884  1.1  mrg 
   1885  1.1  mrg   /* If speculation does not contain the type in question, ignore it.  */
   1886  1.1  mrg   if (otr_type
   1887  1.1  mrg       && !contains_type_p (spec_outer_type, spec_offset, otr_type, false, true))
   1888  1.1  mrg     return false;
   1889  1.1  mrg 
   1890  1.1  mrg   /* If outer type already contains speculation as a filed,
   1891  1.1  mrg      it is useless.  We already know from OUTER_TYPE
   1892  1.1  mrg      SPEC_TYPE and that it is not in the construction.  */
   1893  1.1  mrg   if (contains_type_p (outer_type, offset - spec_offset,
   1894  1.1  mrg 		       spec_outer_type, false, false))
   1895  1.1  mrg     return false;
   1896  1.1  mrg 
   1897  1.1  mrg   /* If speculative outer type is not more specified than outer
   1898  1.1  mrg      type, just give up.
   1899  1.1  mrg      We can only decide this safely if we can compare types with OUTER_TYPE.
   1900  1.1  mrg    */
   1901  1.1  mrg   if ((!in_lto_p || odr_type_p (outer_type))
   1902  1.1  mrg       && !contains_type_p (spec_outer_type,
   1903  1.1  mrg 			   spec_offset - offset,
   1904  1.1  mrg 			   outer_type, false))
   1905  1.1  mrg     return false;
   1906  1.1  mrg   return true;
   1907  1.1  mrg }
   1908  1.1  mrg 
   1909  1.1  mrg /* Improve THIS with speculation described by NEW_OUTER_TYPE, NEW_OFFSET,
   1910  1.1  mrg    NEW_MAYBE_DERIVED_TYPE
   1911  1.1  mrg    If OTR_TYPE is set, assume the context is used with OTR_TYPE.  */
   1912  1.1  mrg 
   1913  1.1  mrg bool
   1914  1.1  mrg ipa_polymorphic_call_context::combine_speculation_with
   1915  1.1  mrg    (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
   1916  1.1  mrg     tree otr_type)
   1917  1.1  mrg {
   1918  1.1  mrg   if (!new_outer_type)
   1919  1.1  mrg     return false;
   1920  1.1  mrg 
   1921  1.1  mrg   /* restrict_to_inner_class may eliminate wrong speculation making our job
   1922  1.1  mrg      easier.  */
   1923  1.1  mrg   if (otr_type)
   1924  1.1  mrg     restrict_to_inner_class (otr_type);
   1925  1.1  mrg 
   1926  1.1  mrg   if (!speculation_consistent_p (new_outer_type, new_offset,
   1927  1.1  mrg 				 new_maybe_derived_type, otr_type))
   1928  1.1  mrg     return false;
   1929  1.1  mrg 
   1930  1.1  mrg   /* New speculation is a win in case we have no speculation or new
   1931  1.1  mrg      speculation does not consider derivations.  */
   1932  1.1  mrg   if (!speculative_outer_type
   1933  1.1  mrg       || (speculative_maybe_derived_type
   1934  1.1  mrg 	  && !new_maybe_derived_type))
   1935  1.1  mrg     {
   1936  1.1  mrg       speculative_outer_type = new_outer_type;
   1937  1.1  mrg       speculative_offset = new_offset;
   1938  1.1  mrg       speculative_maybe_derived_type = new_maybe_derived_type;
   1939  1.1  mrg       return true;
   1940  1.1  mrg     }
   1941  1.1  mrg   else if (types_must_be_same_for_odr (speculative_outer_type,
   1942  1.1  mrg 				       new_outer_type))
   1943  1.1  mrg     {
   1944  1.1  mrg       if (speculative_offset != new_offset)
   1945  1.1  mrg 	{
   1946  1.1  mrg 	  /* OK we have two contexts that seems valid but they disagree,
   1947  1.1  mrg 	     just give up.
   1948  1.1  mrg 
   1949  1.1  mrg 	     This is not a lattice operation, so we may want to drop it later.  */
   1950  1.1  mrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
   1951  1.1  mrg 	    fprintf (dump_file,
   1952  1.1  mrg 		     "Speculative outer types match, "
   1953  1.1  mrg 		     "offset mismatch -> invalid speculation\n");
   1954  1.1  mrg 	  clear_speculation ();
   1955  1.1  mrg 	  return true;
   1956  1.1  mrg 	}
   1957  1.1  mrg       else
   1958  1.1  mrg 	{
   1959  1.1  mrg 	  if (speculative_maybe_derived_type && !new_maybe_derived_type)
   1960  1.1  mrg 	    {
   1961  1.1  mrg 	      speculative_maybe_derived_type = false;
   1962  1.1  mrg 	      return true;
   1963  1.1  mrg 	    }
   1964  1.1  mrg 	  else
   1965  1.1  mrg 	    return false;
   1966  1.1  mrg 	}
   1967  1.1  mrg     }
   1968  1.1  mrg   /* Choose type that contains the other.  This one either contains the outer
   1969  1.1  mrg      as a field (thus giving exactly one target) or is deeper in the type
   1970  1.1  mrg      hierarchy.  */
   1971  1.1  mrg   else if (speculative_outer_type
   1972  1.1  mrg 	   && speculative_maybe_derived_type
   1973  1.1  mrg 	   && (new_offset > speculative_offset
   1974  1.1  mrg 	       || (new_offset == speculative_offset
   1975  1.1  mrg 		   && contains_type_p (new_outer_type,
   1976  1.1  mrg 				       0, speculative_outer_type, false))))
   1977  1.1  mrg     {
   1978  1.1  mrg       tree old_outer_type = speculative_outer_type;
   1979  1.1  mrg       HOST_WIDE_INT old_offset = speculative_offset;
   1980  1.1  mrg       bool old_maybe_derived_type = speculative_maybe_derived_type;
   1981  1.1  mrg 
   1982  1.1  mrg       speculative_outer_type = new_outer_type;
   1983  1.1  mrg       speculative_offset = new_offset;
   1984  1.1  mrg       speculative_maybe_derived_type = new_maybe_derived_type;
   1985  1.1  mrg 
   1986  1.1  mrg       if (otr_type)
   1987  1.1  mrg 	restrict_to_inner_class (otr_type);
   1988  1.1  mrg 
   1989  1.1  mrg       /* If the speculation turned out to make no sense, revert to sensible
   1990  1.1  mrg 	 one.  */
   1991  1.1  mrg       if (!speculative_outer_type)
   1992  1.1  mrg 	{
   1993  1.1  mrg 	  speculative_outer_type = old_outer_type;
   1994  1.1  mrg 	  speculative_offset = old_offset;
   1995  1.1  mrg 	  speculative_maybe_derived_type = old_maybe_derived_type;
   1996  1.1  mrg 	  return false;
   1997  1.1  mrg 	}
   1998  1.1  mrg       return (old_offset != speculative_offset
   1999  1.1  mrg 	      || old_maybe_derived_type != speculative_maybe_derived_type
   2000  1.1  mrg 	      || types_must_be_same_for_odr (speculative_outer_type,
   2001  1.1  mrg 					     new_outer_type));
   2002  1.1  mrg     }
   2003  1.1  mrg   return false;
   2004  1.1  mrg }
   2005  1.1  mrg 
   2006  1.1  mrg /* Make speculation less specific so
   2007  1.1  mrg    NEW_OUTER_TYPE, NEW_OFFSET, NEW_MAYBE_DERIVED_TYPE is also included.
   2008  1.1  mrg    If OTR_TYPE is set, assume the context is used with OTR_TYPE.  */
   2009  1.1  mrg 
   2010  1.1  mrg bool
   2011  1.1  mrg ipa_polymorphic_call_context::meet_speculation_with
   2012  1.1  mrg    (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
   2013  1.1  mrg     tree otr_type)
   2014  1.1  mrg {
   2015  1.1  mrg   if (!new_outer_type && speculative_outer_type)
   2016  1.1  mrg     {
   2017  1.1  mrg       clear_speculation ();
   2018  1.1  mrg       return true;
   2019  1.1  mrg     }
   2020  1.1  mrg 
   2021  1.1  mrg   /* restrict_to_inner_class may eliminate wrong speculation making our job
   2022  1.1  mrg      easier.  */
   2023  1.1  mrg   if (otr_type)
   2024  1.1  mrg     restrict_to_inner_class (otr_type);
   2025  1.1  mrg 
   2026  1.1  mrg   if (!speculative_outer_type
   2027  1.1  mrg       || !speculation_consistent_p (speculative_outer_type,
   2028  1.1  mrg 				    speculative_offset,
   2029  1.1  mrg 				    speculative_maybe_derived_type,
   2030  1.1  mrg 				    otr_type))
   2031  1.1  mrg     return false;
   2032  1.1  mrg 
   2033  1.1  mrg   if (!speculation_consistent_p (new_outer_type, new_offset,
   2034  1.1  mrg 				 new_maybe_derived_type, otr_type))
   2035  1.1  mrg     {
   2036  1.1  mrg       clear_speculation ();
   2037  1.1  mrg       return true;
   2038  1.1  mrg     }
   2039  1.1  mrg 
   2040  1.1  mrg   else if (types_must_be_same_for_odr (speculative_outer_type,
   2041  1.1  mrg 				       new_outer_type))
   2042  1.1  mrg     {
   2043  1.1  mrg       if (speculative_offset != new_offset)
   2044  1.1  mrg 	{
   2045  1.1  mrg 	  clear_speculation ();
   2046  1.1  mrg 	  return true;
   2047  1.1  mrg 	}
   2048  1.1  mrg       else
   2049  1.1  mrg 	{
   2050  1.1  mrg 	  if (!speculative_maybe_derived_type && new_maybe_derived_type)
   2051  1.1  mrg 	    {
   2052  1.1  mrg 	      speculative_maybe_derived_type = true;
   2053  1.1  mrg 	      return true;
   2054  1.1  mrg 	    }
   2055  1.1  mrg 	  else
   2056  1.1  mrg 	    return false;
   2057  1.1  mrg 	}
   2058  1.1  mrg     }
   2059  1.1  mrg   /* See if one type contains the other as a field (not base).  */
   2060  1.1  mrg   else if (contains_type_p (new_outer_type, new_offset - speculative_offset,
   2061  1.1  mrg 			    speculative_outer_type, false, false))
   2062  1.1  mrg     return false;
   2063  1.1  mrg   else if (contains_type_p (speculative_outer_type,
   2064  1.1  mrg 			    speculative_offset - new_offset,
   2065  1.1  mrg 			    new_outer_type, false, false))
   2066  1.1  mrg     {
   2067  1.1  mrg       speculative_outer_type = new_outer_type;
   2068  1.1  mrg       speculative_offset = new_offset;
   2069  1.1  mrg       speculative_maybe_derived_type = new_maybe_derived_type;
   2070  1.1  mrg       return true;
   2071  1.1  mrg     }
   2072  1.1  mrg   /* See if OUTER_TYPE is base of CTX.OUTER_TYPE.  */
   2073  1.1  mrg   else if (contains_type_p (new_outer_type,
   2074  1.1  mrg 			    new_offset - speculative_offset,
   2075  1.1  mrg 			    speculative_outer_type, false, true))
   2076  1.1  mrg     {
   2077  1.1  mrg       if (!speculative_maybe_derived_type)
   2078  1.1  mrg 	{
   2079  1.1  mrg 	  speculative_maybe_derived_type = true;
   2080  1.1  mrg 	  return true;
   2081  1.1  mrg 	}
   2082  1.1  mrg       return false;
   2083  1.1  mrg     }
   2084  1.1  mrg   /* See if CTX.OUTER_TYPE is base of OUTER_TYPE.  */
   2085  1.1  mrg   else if (contains_type_p (speculative_outer_type,
   2086  1.1  mrg 			    speculative_offset - new_offset, new_outer_type, false, true))
   2087  1.1  mrg     {
   2088  1.1  mrg       speculative_outer_type = new_outer_type;
   2089  1.1  mrg       speculative_offset = new_offset;
   2090  1.1  mrg       speculative_maybe_derived_type = true;
   2091  1.1  mrg       return true;
   2092  1.1  mrg     }
   2093  1.1  mrg   else
   2094  1.1  mrg     {
   2095  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2096  1.1  mrg         fprintf (dump_file, "Giving up on speculative meet\n");
   2097  1.1  mrg       clear_speculation ();
   2098  1.1  mrg       return true;
   2099  1.1  mrg     }
   2100  1.1  mrg }
   2101  1.1  mrg 
   2102  1.1  mrg /* Assume that both THIS and a given context is valid and strengthen THIS
   2103  1.1  mrg    if possible.  Return true if any strengthening was made.
   2104  1.1  mrg    If actual type the context is being used in is known, OTR_TYPE should be
   2105  1.1  mrg    set accordingly. This improves quality of combined result.  */
   2106  1.1  mrg 
   2107  1.1  mrg bool
   2108  1.1  mrg ipa_polymorphic_call_context::combine_with (ipa_polymorphic_call_context ctx,
   2109  1.1  mrg 					    tree otr_type)
   2110  1.1  mrg {
   2111  1.1  mrg   bool updated = false;
   2112  1.1  mrg 
   2113  1.1  mrg   if (ctx.useless_p () || invalid)
   2114  1.1  mrg     return false;
   2115  1.1  mrg 
   2116  1.1  mrg   /* Restricting context to inner type makes merging easier, however do not
   2117  1.1  mrg      do that unless we know how the context is used (OTR_TYPE is non-NULL)  */
   2118  1.1  mrg   if (otr_type && !invalid && !ctx.invalid)
   2119  1.1  mrg     {
   2120  1.1  mrg       restrict_to_inner_class (otr_type);
   2121  1.1  mrg       ctx.restrict_to_inner_class (otr_type);
   2122  1.1  mrg       if(invalid)
   2123  1.1  mrg         return false;
   2124  1.1  mrg     }
   2125  1.1  mrg 
   2126  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS))
   2127  1.1  mrg     {
   2128  1.1  mrg       fprintf (dump_file, "Polymorphic call context combine:");
   2129  1.1  mrg       dump (dump_file);
   2130  1.1  mrg       fprintf (dump_file, "With context:                    ");
   2131  1.1  mrg       ctx.dump (dump_file);
   2132  1.1  mrg       if (otr_type)
   2133  1.1  mrg 	{
   2134  1.1  mrg           fprintf (dump_file, "To be used with type:            ");
   2135  1.1  mrg 	  print_generic_expr (dump_file, otr_type, TDF_SLIM);
   2136  1.1  mrg           fprintf (dump_file, "\n");
   2137  1.1  mrg 	}
   2138  1.1  mrg     }
   2139  1.1  mrg 
   2140  1.1  mrg   /* If call is known to be invalid, we are done.  */
   2141  1.1  mrg   if (ctx.invalid)
   2142  1.1  mrg     {
   2143  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2144  1.1  mrg         fprintf (dump_file, "-> Invalid context\n");
   2145  1.1  mrg       goto invalidate;
   2146  1.1  mrg     }
   2147  1.1  mrg 
   2148  1.1  mrg   if (!ctx.outer_type)
   2149  1.1  mrg     ;
   2150  1.1  mrg   else if (!outer_type)
   2151  1.1  mrg     {
   2152  1.1  mrg       outer_type = ctx.outer_type;
   2153  1.1  mrg       offset = ctx.offset;
   2154  1.1  mrg       dynamic = ctx.dynamic;
   2155  1.1  mrg       maybe_in_construction = ctx.maybe_in_construction;
   2156  1.1  mrg       maybe_derived_type = ctx.maybe_derived_type;
   2157  1.1  mrg       updated = true;
   2158  1.1  mrg     }
   2159  1.1  mrg   /* If types are known to be same, merging is quite easy.  */
   2160  1.1  mrg   else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
   2161  1.1  mrg     {
   2162  1.1  mrg       if (offset != ctx.offset
   2163  1.1  mrg 	  && TYPE_SIZE (outer_type)
   2164  1.1  mrg 	  && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
   2165  1.1  mrg 	{
   2166  1.1  mrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
   2167  1.1  mrg 	    fprintf (dump_file, "Outer types match, offset mismatch -> invalid\n");
   2168  1.1  mrg 	  clear_speculation ();
   2169  1.1  mrg 	  clear_outer_type ();
   2170  1.1  mrg 	  invalid = true;
   2171  1.1  mrg 	  return true;
   2172  1.1  mrg 	}
   2173  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2174  1.1  mrg         fprintf (dump_file, "Outer types match, merging flags\n");
   2175  1.1  mrg       if (maybe_in_construction && !ctx.maybe_in_construction)
   2176  1.1  mrg 	{
   2177  1.1  mrg 	  updated = true;
   2178  1.1  mrg 	  maybe_in_construction = false;
   2179  1.1  mrg 	}
   2180  1.1  mrg       if (maybe_derived_type && !ctx.maybe_derived_type)
   2181  1.1  mrg 	{
   2182  1.1  mrg 	  updated = true;
   2183  1.1  mrg 	  maybe_derived_type = false;
   2184  1.1  mrg 	}
   2185  1.1  mrg       if (dynamic && !ctx.dynamic)
   2186  1.1  mrg 	{
   2187  1.1  mrg 	  updated = true;
   2188  1.1  mrg 	  dynamic = false;
   2189  1.1  mrg 	}
   2190  1.1  mrg     }
   2191  1.1  mrg   /* If we know the type precisely, there is not much to improve.  */
   2192  1.1  mrg   else if (!maybe_derived_type && !maybe_in_construction
   2193  1.1  mrg 	   && !ctx.maybe_derived_type && !ctx.maybe_in_construction)
   2194  1.1  mrg     {
   2195  1.1  mrg       /* It may be easy to check if second context permits the first
   2196  1.1  mrg 	 and set INVALID otherwise.  This is not easy to do in general;
   2197  1.1  mrg 	 contains_type_p may return false negatives for non-comparable
   2198  1.1  mrg 	 types.
   2199  1.1  mrg 
   2200  1.1  mrg 	 If OTR_TYPE is known, we however can expect that
   2201  1.1  mrg 	 restrict_to_inner_class should have discovered the same base
   2202  1.1  mrg 	 type.  */
   2203  1.1  mrg       if (otr_type && !ctx.maybe_in_construction && !ctx.maybe_derived_type)
   2204  1.1  mrg 	{
   2205  1.1  mrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
   2206  1.1  mrg 	    fprintf (dump_file, "Contextes disagree -> invalid\n");
   2207  1.1  mrg 	  goto invalidate;
   2208  1.1  mrg 	}
   2209  1.1  mrg     }
   2210  1.1  mrg   /* See if one type contains the other as a field (not base).
   2211  1.1  mrg      In this case we want to choose the wider type, because it contains
   2212  1.1  mrg      more information.  */
   2213  1.1  mrg   else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
   2214  1.1  mrg 			    outer_type, false, false))
   2215  1.1  mrg     {
   2216  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2217  1.1  mrg 	fprintf (dump_file, "Second type contain the first as a field\n");
   2218  1.1  mrg 
   2219  1.1  mrg       if (maybe_derived_type)
   2220  1.1  mrg 	{
   2221  1.1  mrg 	  outer_type = ctx.outer_type;
   2222  1.1  mrg 	  maybe_derived_type = ctx.maybe_derived_type;
   2223  1.1  mrg 	  offset = ctx.offset;
   2224  1.1  mrg 	  dynamic = ctx.dynamic;
   2225  1.1  mrg 	  updated = true;
   2226  1.1  mrg 	}
   2227  1.1  mrg 
   2228  1.1  mrg       /* If we do not know how the context is being used, we cannot
   2229  1.1  mrg 	 clear MAYBE_IN_CONSTRUCTION because it may be offseted
   2230  1.1  mrg 	 to other component of OUTER_TYPE later and we know nothing
   2231  1.1  mrg 	 about it.  */
   2232  1.1  mrg       if (otr_type && maybe_in_construction
   2233  1.1  mrg 	  && !ctx.maybe_in_construction)
   2234  1.1  mrg 	{
   2235  1.1  mrg           maybe_in_construction = false;
   2236  1.1  mrg 	  updated = true;
   2237  1.1  mrg 	}
   2238  1.1  mrg     }
   2239  1.1  mrg   else if (contains_type_p (outer_type, offset - ctx.offset,
   2240  1.1  mrg 			    ctx.outer_type, false, false))
   2241  1.1  mrg     {
   2242  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2243  1.1  mrg 	fprintf (dump_file, "First type contain the second as a field\n");
   2244  1.1  mrg 
   2245  1.1  mrg       if (otr_type && maybe_in_construction
   2246  1.1  mrg 	  && !ctx.maybe_in_construction)
   2247  1.1  mrg 	{
   2248  1.1  mrg           maybe_in_construction = false;
   2249  1.1  mrg 	  updated = true;
   2250  1.1  mrg 	}
   2251  1.1  mrg     }
   2252  1.1  mrg   /* See if OUTER_TYPE is base of CTX.OUTER_TYPE.  */
   2253  1.1  mrg   else if (contains_type_p (ctx.outer_type,
   2254  1.1  mrg 			    ctx.offset - offset, outer_type, false, true))
   2255  1.1  mrg     {
   2256  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2257  1.1  mrg 	fprintf (dump_file, "First type is base of second\n");
   2258  1.1  mrg       if (!maybe_derived_type)
   2259  1.1  mrg 	{
   2260  1.1  mrg 	  if (!ctx.maybe_in_construction
   2261  1.1  mrg 	      && types_odr_comparable (outer_type, ctx.outer_type))
   2262  1.1  mrg 	    {
   2263  1.1  mrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
   2264  1.1  mrg 		fprintf (dump_file, "Second context does not permit base -> invalid\n");
   2265  1.1  mrg 	      goto invalidate;
   2266  1.1  mrg 	    }
   2267  1.1  mrg 	}
   2268  1.1  mrg       /* Pick variant deeper in the hierarchy.  */
   2269  1.1  mrg       else
   2270  1.1  mrg 	{
   2271  1.1  mrg 	  outer_type = ctx.outer_type;
   2272  1.1  mrg 	  maybe_in_construction = ctx.maybe_in_construction;
   2273  1.1  mrg 	  maybe_derived_type = ctx.maybe_derived_type;
   2274  1.1  mrg 	  offset = ctx.offset;
   2275  1.1  mrg 	  dynamic = ctx.dynamic;
   2276  1.1  mrg           updated = true;
   2277  1.1  mrg 	}
   2278  1.1  mrg     }
   2279  1.1  mrg   /* See if CTX.OUTER_TYPE is base of OUTER_TYPE.  */
   2280  1.1  mrg   else if (contains_type_p (outer_type,
   2281  1.1  mrg 			    offset - ctx.offset, ctx.outer_type, false, true))
   2282  1.1  mrg     {
   2283  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2284  1.1  mrg 	fprintf (dump_file, "Second type is base of first\n");
   2285  1.1  mrg       if (!ctx.maybe_derived_type)
   2286  1.1  mrg 	{
   2287  1.1  mrg 	  if (!maybe_in_construction
   2288  1.1  mrg 	      && types_odr_comparable (outer_type, ctx.outer_type))
   2289  1.1  mrg 	    {
   2290  1.1  mrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
   2291  1.1  mrg 		fprintf (dump_file, "First context does not permit base -> invalid\n");
   2292  1.1  mrg 	      goto invalidate;
   2293  1.1  mrg 	    }
   2294  1.1  mrg 	  /* Pick the base type.  */
   2295  1.1  mrg 	  else if (maybe_in_construction)
   2296  1.1  mrg 	    {
   2297  1.1  mrg 	      outer_type = ctx.outer_type;
   2298  1.1  mrg 	      maybe_in_construction = ctx.maybe_in_construction;
   2299  1.1  mrg 	      maybe_derived_type = ctx.maybe_derived_type;
   2300  1.1  mrg 	      offset = ctx.offset;
   2301  1.1  mrg 	      dynamic = ctx.dynamic;
   2302  1.1  mrg 	      updated = true;
   2303  1.1  mrg 	    }
   2304  1.1  mrg 	}
   2305  1.1  mrg     }
   2306  1.1  mrg   /* TODO handle merging using hierarchy. */
   2307  1.1  mrg   else if (dump_file && (dump_flags & TDF_DETAILS))
   2308  1.1  mrg     fprintf (dump_file, "Giving up on merge\n");
   2309  1.1  mrg 
   2310  1.1  mrg   updated |= combine_speculation_with (ctx.speculative_outer_type,
   2311  1.1  mrg 				       ctx.speculative_offset,
   2312  1.1  mrg 				       ctx.speculative_maybe_derived_type,
   2313  1.1  mrg 				       otr_type);
   2314  1.1  mrg 
   2315  1.1  mrg   if (updated && dump_file && (dump_flags & TDF_DETAILS))
   2316  1.1  mrg     {
   2317  1.1  mrg       fprintf (dump_file, "Updated as:                      ");
   2318  1.1  mrg       dump (dump_file);
   2319  1.1  mrg       fprintf (dump_file, "\n");
   2320  1.1  mrg     }
   2321  1.1  mrg   return updated;
   2322  1.1  mrg 
   2323  1.1  mrg invalidate:
   2324  1.1  mrg   invalid = true;
   2325  1.1  mrg   clear_speculation ();
   2326  1.1  mrg   clear_outer_type ();
   2327  1.1  mrg   return true;
   2328  1.1  mrg }
   2329  1.1  mrg 
   2330  1.1  mrg /* Take non-speculative info, merge it with speculative and clear speculation.
   2331  1.1  mrg    Used when we no longer manage to keep track of actual outer type, but we
   2332  1.1  mrg    think it is still there.
   2333  1.1  mrg 
   2334  1.1  mrg    If OTR_TYPE is set, the transformation can be done more effectively assuming
   2335  1.1  mrg    that context is going to be used only that way.  */
   2336  1.1  mrg 
   2337  1.1  mrg void
   2338  1.1  mrg ipa_polymorphic_call_context::make_speculative (tree otr_type)
   2339  1.1  mrg {
   2340  1.1  mrg   tree spec_outer_type = outer_type;
   2341  1.1  mrg   HOST_WIDE_INT spec_offset = offset;
   2342  1.1  mrg   bool spec_maybe_derived_type = maybe_derived_type;
   2343  1.1  mrg 
   2344  1.1  mrg   if (invalid)
   2345  1.1  mrg     {
   2346  1.1  mrg       invalid = false;
   2347  1.1  mrg       clear_outer_type ();
   2348  1.1  mrg       clear_speculation ();
   2349  1.1  mrg       return;
   2350  1.1  mrg     }
   2351  1.1  mrg   if (!outer_type)
   2352  1.1  mrg     return;
   2353  1.1  mrg   clear_outer_type ();
   2354  1.1  mrg   combine_speculation_with (spec_outer_type, spec_offset,
   2355  1.1  mrg 			    spec_maybe_derived_type,
   2356  1.1  mrg 			    otr_type);
   2357  1.1  mrg }
   2358  1.1  mrg 
   2359  1.1  mrg /* Use when we cannot track dynamic type change.  This speculatively assume
   2360  1.1  mrg    type change is not happening.  */
   2361  1.1  mrg 
   2362  1.1  mrg void
   2363  1.1  mrg ipa_polymorphic_call_context::possible_dynamic_type_change (bool in_poly_cdtor,
   2364  1.1  mrg 							    tree otr_type)
   2365  1.1  mrg {
   2366  1.1  mrg   if (dynamic)
   2367  1.1  mrg     make_speculative (otr_type);
   2368  1.1  mrg   else if (in_poly_cdtor)
   2369  1.1  mrg     maybe_in_construction = true;
   2370  1.1  mrg }
   2371  1.1  mrg 
   2372  1.1  mrg /* Return TRUE if this context conveys the same information as OTHER.  */
   2373  1.1  mrg 
   2374  1.1  mrg bool
   2375  1.1  mrg ipa_polymorphic_call_context::equal_to
   2376  1.1  mrg     (const ipa_polymorphic_call_context &x) const
   2377  1.1  mrg {
   2378  1.1  mrg   if (useless_p ())
   2379  1.1  mrg     return x.useless_p ();
   2380  1.1  mrg   if (invalid)
   2381  1.1  mrg     return x.invalid;
   2382  1.1  mrg   if (x.useless_p () || x.invalid)
   2383  1.1  mrg     return false;
   2384  1.1  mrg 
   2385  1.1  mrg   if (outer_type)
   2386  1.1  mrg     {
   2387  1.1  mrg       if (!x.outer_type
   2388  1.1  mrg 	  || !types_odr_comparable (outer_type, x.outer_type)
   2389  1.1  mrg 	  || !types_same_for_odr (outer_type, x.outer_type)
   2390  1.1  mrg 	  || offset != x.offset
   2391  1.1  mrg 	  || maybe_in_construction != x.maybe_in_construction
   2392  1.1  mrg 	  || maybe_derived_type != x.maybe_derived_type
   2393  1.1  mrg 	  || dynamic != x.dynamic)
   2394  1.1  mrg 	return false;
   2395  1.1  mrg     }
   2396  1.1  mrg   else if (x.outer_type)
   2397  1.1  mrg     return false;
   2398  1.1  mrg 
   2399  1.1  mrg 
   2400  1.1  mrg   if (speculative_outer_type
   2401  1.1  mrg       && speculation_consistent_p (speculative_outer_type, speculative_offset,
   2402  1.1  mrg 				   speculative_maybe_derived_type, NULL_TREE))
   2403  1.1  mrg     {
   2404  1.1  mrg       if (!x.speculative_outer_type)
   2405  1.1  mrg 	return false;
   2406  1.1  mrg 
   2407  1.1  mrg       if (!types_odr_comparable (speculative_outer_type,
   2408  1.1  mrg 				 x.speculative_outer_type)
   2409  1.1  mrg 	  || !types_same_for_odr  (speculative_outer_type,
   2410  1.1  mrg 				   x.speculative_outer_type)
   2411  1.1  mrg 	  || speculative_offset != x.speculative_offset
   2412  1.1  mrg 	  || speculative_maybe_derived_type != x.speculative_maybe_derived_type)
   2413  1.1  mrg 	return false;
   2414  1.1  mrg     }
   2415  1.1  mrg   else if (x.speculative_outer_type
   2416  1.1  mrg 	   && x.speculation_consistent_p (x.speculative_outer_type,
   2417  1.1  mrg 					  x.speculative_offset,
   2418  1.1  mrg 				  	  x.speculative_maybe_derived_type,
   2419  1.1  mrg 					  NULL))
   2420  1.1  mrg     return false;
   2421  1.1  mrg 
   2422  1.1  mrg   return true;
   2423  1.1  mrg }
   2424  1.1  mrg 
   2425  1.1  mrg /* Modify context to be strictly less restrictive than CTX.  */
   2426  1.1  mrg 
   2427  1.1  mrg bool
   2428  1.1  mrg ipa_polymorphic_call_context::meet_with (ipa_polymorphic_call_context ctx,
   2429  1.1  mrg 					 tree otr_type)
   2430  1.1  mrg {
   2431  1.1  mrg   bool updated = false;
   2432  1.1  mrg 
   2433  1.1  mrg   if (useless_p () || ctx.invalid)
   2434  1.1  mrg     return false;
   2435  1.1  mrg 
   2436  1.1  mrg   /* Restricting context to inner type makes merging easier, however do not
   2437  1.1  mrg      do that unless we know how the context is used (OTR_TYPE is non-NULL)  */
   2438  1.1  mrg   if (otr_type && !useless_p () && !ctx.useless_p ())
   2439  1.1  mrg     {
   2440  1.1  mrg       restrict_to_inner_class (otr_type);
   2441  1.1  mrg       ctx.restrict_to_inner_class (otr_type);
   2442  1.1  mrg       if(invalid)
   2443  1.1  mrg         return false;
   2444  1.1  mrg     }
   2445  1.1  mrg 
   2446  1.1  mrg   if (equal_to (ctx))
   2447  1.1  mrg     return false;
   2448  1.1  mrg 
   2449  1.1  mrg   if (ctx.useless_p () || invalid)
   2450  1.1  mrg     {
   2451  1.1  mrg       *this = ctx;
   2452  1.1  mrg       return true;
   2453  1.1  mrg     }
   2454  1.1  mrg 
   2455  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS))
   2456  1.1  mrg     {
   2457  1.1  mrg       fprintf (dump_file, "Polymorphic call context meet:");
   2458  1.1  mrg       dump (dump_file);
   2459  1.1  mrg       fprintf (dump_file, "With context:                    ");
   2460  1.1  mrg       ctx.dump (dump_file);
   2461  1.1  mrg       if (otr_type)
   2462  1.1  mrg 	{
   2463  1.1  mrg           fprintf (dump_file, "To be used with type:            ");
   2464  1.1  mrg 	  print_generic_expr (dump_file, otr_type, TDF_SLIM);
   2465  1.1  mrg           fprintf (dump_file, "\n");
   2466  1.1  mrg 	}
   2467  1.1  mrg     }
   2468  1.1  mrg 
   2469  1.1  mrg   if (!dynamic && ctx.dynamic)
   2470  1.1  mrg     {
   2471  1.1  mrg       dynamic = true;
   2472  1.1  mrg       updated = true;
   2473  1.1  mrg     }
   2474  1.1  mrg 
   2475  1.1  mrg   /* If call is known to be invalid, we are done.  */
   2476  1.1  mrg   if (!outer_type)
   2477  1.1  mrg     ;
   2478  1.1  mrg   else if (!ctx.outer_type)
   2479  1.1  mrg     {
   2480  1.1  mrg       clear_outer_type ();
   2481  1.1  mrg       updated = true;
   2482  1.1  mrg     }
   2483  1.1  mrg   /* If types are known to be same, merging is quite easy.  */
   2484  1.1  mrg   else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
   2485  1.1  mrg     {
   2486  1.1  mrg       if (offset != ctx.offset
   2487  1.1  mrg 	  && TYPE_SIZE (outer_type)
   2488  1.1  mrg 	  && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
   2489  1.1  mrg 	{
   2490  1.1  mrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
   2491  1.1  mrg 	    fprintf (dump_file, "Outer types match, offset mismatch -> clearing\n");
   2492  1.1  mrg 	  clear_outer_type ();
   2493  1.1  mrg 	  return true;
   2494  1.1  mrg 	}
   2495  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2496  1.1  mrg         fprintf (dump_file, "Outer types match, merging flags\n");
   2497  1.1  mrg       if (!maybe_in_construction && ctx.maybe_in_construction)
   2498  1.1  mrg 	{
   2499  1.1  mrg 	  updated = true;
   2500  1.1  mrg 	  maybe_in_construction = true;
   2501  1.1  mrg 	}
   2502  1.1  mrg       if (!maybe_derived_type && ctx.maybe_derived_type)
   2503  1.1  mrg 	{
   2504  1.1  mrg 	  updated = true;
   2505  1.1  mrg 	  maybe_derived_type = true;
   2506  1.1  mrg 	}
   2507  1.1  mrg       if (!dynamic && ctx.dynamic)
   2508  1.1  mrg 	{
   2509  1.1  mrg 	  updated = true;
   2510  1.1  mrg 	  dynamic = true;
   2511  1.1  mrg 	}
   2512  1.1  mrg     }
   2513  1.1  mrg   /* See if one type contains the other as a field (not base).  */
   2514  1.1  mrg   else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
   2515  1.1  mrg 			    outer_type, false, false))
   2516  1.1  mrg     {
   2517  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2518  1.1  mrg 	fprintf (dump_file, "Second type contain the first as a field\n");
   2519  1.1  mrg 
   2520  1.1  mrg       /* The second type is more specified, so we keep the first.
   2521  1.1  mrg          We need to set DYNAMIC flag to avoid declaring context INVALID
   2522  1.1  mrg 	 of OFFSET ends up being out of range.  */
   2523  1.1  mrg       if (!dynamic
   2524  1.1  mrg 	  && (ctx.dynamic
   2525  1.1  mrg 	      || (!otr_type
   2526  1.1  mrg 		  && (!TYPE_SIZE (ctx.outer_type)
   2527  1.1  mrg 		      || !TYPE_SIZE (outer_type)
   2528  1.1  mrg 		      || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
   2529  1.1  mrg 					   TYPE_SIZE (outer_type), 0)))))
   2530  1.1  mrg 	{
   2531  1.1  mrg 	  dynamic = true;
   2532  1.1  mrg 	  updated = true;
   2533  1.1  mrg 	}
   2534  1.1  mrg     }
   2535  1.1  mrg   else if (contains_type_p (outer_type, offset - ctx.offset,
   2536  1.1  mrg 			    ctx.outer_type, false, false))
   2537  1.1  mrg     {
   2538  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2539  1.1  mrg 	fprintf (dump_file, "First type contain the second as a field\n");
   2540  1.1  mrg 
   2541  1.1  mrg       if (!dynamic
   2542  1.1  mrg 	  && (ctx.dynamic
   2543  1.1  mrg 	      || (!otr_type
   2544  1.1  mrg 		  && (!TYPE_SIZE (ctx.outer_type)
   2545  1.1  mrg 		      || !TYPE_SIZE (outer_type)
   2546  1.1  mrg 		      || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
   2547  1.1  mrg 					   TYPE_SIZE (outer_type), 0)))))
   2548  1.1  mrg 	dynamic = true;
   2549  1.1  mrg       outer_type = ctx.outer_type;
   2550  1.1  mrg       offset = ctx.offset;
   2551  1.1  mrg       dynamic = ctx.dynamic;
   2552  1.1  mrg       maybe_in_construction = ctx.maybe_in_construction;
   2553  1.1  mrg       maybe_derived_type = ctx.maybe_derived_type;
   2554  1.1  mrg       updated = true;
   2555  1.1  mrg     }
   2556  1.1  mrg   /* See if OUTER_TYPE is base of CTX.OUTER_TYPE.  */
   2557  1.1  mrg   else if (contains_type_p (ctx.outer_type,
   2558  1.1  mrg 			    ctx.offset - offset, outer_type, false, true))
   2559  1.1  mrg     {
   2560  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2561  1.1  mrg 	fprintf (dump_file, "First type is base of second\n");
   2562  1.1  mrg       if (!maybe_derived_type)
   2563  1.1  mrg 	{
   2564  1.1  mrg 	  maybe_derived_type = true;
   2565  1.1  mrg 	  updated = true;
   2566  1.1  mrg 	}
   2567  1.1  mrg       if (!maybe_in_construction && ctx.maybe_in_construction)
   2568  1.1  mrg 	{
   2569  1.1  mrg 	  maybe_in_construction = true;
   2570  1.1  mrg 	  updated = true;
   2571  1.1  mrg 	}
   2572  1.1  mrg       if (!dynamic && ctx.dynamic)
   2573  1.1  mrg 	{
   2574  1.1  mrg 	  dynamic = true;
   2575  1.1  mrg 	  updated = true;
   2576  1.1  mrg 	}
   2577  1.1  mrg     }
   2578  1.1  mrg   /* See if CTX.OUTER_TYPE is base of OUTER_TYPE.  */
   2579  1.1  mrg   else if (contains_type_p (outer_type,
   2580  1.1  mrg 			    offset - ctx.offset, ctx.outer_type, false, true))
   2581  1.1  mrg     {
   2582  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2583  1.1  mrg 	fprintf (dump_file, "Second type is base of first\n");
   2584  1.1  mrg       outer_type = ctx.outer_type;
   2585  1.1  mrg       offset = ctx.offset;
   2586  1.1  mrg       updated = true;
   2587  1.1  mrg       if (!maybe_derived_type)
   2588  1.1  mrg 	maybe_derived_type = true;
   2589  1.1  mrg       if (!maybe_in_construction && ctx.maybe_in_construction)
   2590  1.1  mrg 	maybe_in_construction = true;
   2591  1.1  mrg       if (!dynamic && ctx.dynamic)
   2592  1.1  mrg 	dynamic = true;
   2593  1.1  mrg     }
   2594  1.1  mrg   /* TODO handle merging using hierarchy. */
   2595  1.1  mrg   else
   2596  1.1  mrg     {
   2597  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2598  1.1  mrg         fprintf (dump_file, "Giving up on meet\n");
   2599  1.1  mrg       clear_outer_type ();
   2600  1.1  mrg       updated = true;
   2601  1.1  mrg     }
   2602  1.1  mrg 
   2603  1.1  mrg   updated |= meet_speculation_with (ctx.speculative_outer_type,
   2604  1.1  mrg 				    ctx.speculative_offset,
   2605  1.1  mrg 				    ctx.speculative_maybe_derived_type,
   2606  1.1  mrg 				    otr_type);
   2607  1.1  mrg 
   2608  1.1  mrg   if (updated && dump_file && (dump_flags & TDF_DETAILS))
   2609  1.1  mrg     {
   2610  1.1  mrg       fprintf (dump_file, "Updated as:                      ");
   2611  1.1  mrg       dump (dump_file);
   2612  1.1  mrg       fprintf (dump_file, "\n");
   2613  1.1  mrg     }
   2614  1.1  mrg   return updated;
   2615  1.1  mrg }
   2616