/* Analysis of polymorphic call context.
   Copyright (C) 2013-2018 Free Software Foundation, Inc.
   Contributed by Jan Hubicka

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "tree-ssa-operands.h"
#include "streamer-hooks.h"
#include "cgraph.h"
#include "data-streamer.h"
#include "diagnostic.h"
#include "alias.h"
#include "fold-const.h"
#include "calls.h"
#include "ipa-utils.h"
#include "tree-dfa.h"
#include "gimple-pretty-print.h"
#include "tree-into-ssa.h"
#include "params.h"

/* Return true when TYPE contains an polymorphic type and thus is interesting
   for devirtualization machinery.  */

static bool contains_type_p (tree, HOST_WIDE_INT, tree,
			     bool consider_placement_new = true,
			     bool consider_bases = true);

bool
contains_polymorphic_type_p (const_tree type)
{
  type = TYPE_MAIN_VARIANT (type);

  if (RECORD_OR_UNION_TYPE_P (type))
    {
      if (TYPE_BINFO (type)
          && polymorphic_type_binfo_p (TYPE_BINFO (type)))
	return true;
      for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
	if (TREE_CODE (fld) == FIELD_DECL
	    && !DECL_ARTIFICIAL (fld)
	    && contains_polymorphic_type_p (TREE_TYPE (fld)))
	  return true;
      return false;
    }
  if (TREE_CODE (type) == ARRAY_TYPE)
    return contains_polymorphic_type_p (TREE_TYPE (type));
  return false;
}

/* Return true if it seems valid to use placement new to build EXPECTED_TYPE
   at possition CUR_OFFSET within TYPE.  

   POD can be changed to an instance of a polymorphic type by
   placement new.  Here we play safe and assume that any
   non-polymorphic type is POD.  */
bool
possible_placement_new (tree type, tree expected_type,
			HOST_WIDE_INT cur_offset)
{
  if (cur_offset < 0)
    return true;
  return ((TREE_CODE (type) != RECORD_TYPE
	   || !TYPE_BINFO (type)
	   || cur_offset >= POINTER_SIZE
	   || !polymorphic_type_binfo_p (TYPE_BINFO (type)))
	  && (!TYPE_SIZE (type)
	      || !tree_fits_shwi_p (TYPE_SIZE (type))
	      || (cur_offset
		  + (expected_type ? tree_to_uhwi (TYPE_SIZE (expected_type))
		     : POINTER_SIZE)
		  <= tree_to_uhwi (TYPE_SIZE (type)))));
}

/* THIS->OUTER_TYPE is a type of memory object where object of OTR_TYPE
   is contained at THIS->OFFSET.  Walk the memory representation of
   THIS->OUTER_TYPE and find the outermost class type that match
   OTR_TYPE or contain OTR_TYPE as a base.  Update THIS
   to represent it.

   If OTR_TYPE is NULL, just find outermost polymorphic type with
   virtual table present at possition OFFSET.

   For example when THIS represents type
   class A
     {
       int a;
       class B b;
     }
   and we look for type at offset sizeof(int), we end up with B and offset 0.
   If the same is produced by multiple inheritance, we end up with A and offset
   sizeof(int). 

   If we can not find corresponding class, give up by setting
   THIS->OUTER_TYPE to OTR_TYPE and THIS->OFFSET to NULL. 
   Return true when lookup was sucesful.

   When CONSIDER_PLACEMENT_NEW is false, reject contexts that may be made
   valid only via allocation of new polymorphic type inside by means
   of placement new.

   When CONSIDER_BASES is false, only look for actual fields, not base types
   of TYPE.  */

bool
ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type,
						       bool consider_placement_new,
						       bool consider_bases)
{
  tree type = outer_type;
  HOST_WIDE_INT cur_offset = offset;
  bool speculative = false;
  bool size_unknown = false;
  unsigned HOST_WIDE_INT otr_type_size = POINTER_SIZE;

  /* Update OUTER_TYPE to match EXPECTED_TYPE if it is not set.  */
  if (!outer_type)
    {
      clear_outer_type (otr_type);
      type = otr_type;
      cur_offset = 0;
    }
 /* See if OFFSET points inside OUTER_TYPE.  If it does not, we know
    that the context is either invalid, or the instance type must be
    derived from OUTER_TYPE.

    Because the instance type may contain field whose type is of OUTER_TYPE,
    we can not derive any effective information about it.

    TODO: In the case we know all derrived types, we can definitely do better
    here.  */
  else if (TYPE_SIZE (outer_type)
	   && tree_fits_shwi_p (TYPE_SIZE (outer_type))
	   && tree_to_shwi (TYPE_SIZE (outer_type)) >= 0
	   && tree_to_shwi (TYPE_SIZE (outer_type)) <= offset)
   {
     bool der = maybe_derived_type; /* clear_outer_type will reset it.  */
     bool dyn = dynamic;
     clear_outer_type (otr_type);
     type = otr_type;
     cur_offset = 0;

     /* If derived type is not allowed, we know that the context is invalid.
	For dynamic types, we really do not have information about
	size of the memory location.  It is possible that completely
	different type is stored after outer_type.  */
     if (!der && !dyn)
       {
	 clear_speculation ();
	 invalid = true;
	 return false;
       }
   }

  if (otr_type && TYPE_SIZE (otr_type)
      && tree_fits_shwi_p (TYPE_SIZE (otr_type)))
    otr_type_size = tree_to_uhwi (TYPE_SIZE (otr_type));

  if (!type || offset < 0)
    goto no_useful_type_info;

  /* Find the sub-object the constant actually refers to and mark whether it is
     an artificial one (as opposed to a user-defined one).

     This loop is performed twice; first time for outer_type and second time
     for speculative_outer_type.  The second run has SPECULATIVE set.  */
  while (true)
    {
      unsigned HOST_WIDE_INT pos, size;
      tree fld;

      /* If we do not know size of TYPE, we need to be more conservative
         about accepting cases where we can not find EXPECTED_TYPE.
	 Generally the types that do matter here are of constant size.
	 Size_unknown case should be very rare.  */
      if (TYPE_SIZE (type)
	  && tree_fits_shwi_p (TYPE_SIZE (type))
	  && tree_to_shwi (TYPE_SIZE (type)) >= 0)
	size_unknown = false;
      else
	size_unknown = true;

      /* On a match, just return what we found.  */
      if ((otr_type
	   && types_odr_comparable (type, otr_type)
	   && types_same_for_odr (type, otr_type))
	  || (!otr_type
	      && TREE_CODE (type) == RECORD_TYPE
	      && TYPE_BINFO (type)
	      && polymorphic_type_binfo_p (TYPE_BINFO (type))))
	{
	  if (speculative)
	    {
	      /* If we did not match the offset, just give up on speculation.  */
	      if (cur_offset != 0
		  /* Also check if speculation did not end up being same as
		     non-speculation.  */
		  || (types_must_be_same_for_odr (speculative_outer_type,
						  outer_type)
		      && (maybe_derived_type
			  == speculative_maybe_derived_type)))
		clear_speculation ();
	      return true;
	    }
	  else
	    {
	      /* If type is known to be final, do not worry about derived
		 types.  Testing it here may help us to avoid speculation.  */
	      if (otr_type && TREE_CODE (outer_type) == RECORD_TYPE
		  && (!in_lto_p || odr_type_p (outer_type))
		  && type_with_linkage_p (outer_type)
		  && type_known_to_have_no_derivations_p (outer_type))
		maybe_derived_type = false;

	      /* Type can not contain itself on an non-zero offset.  In that case
		 just give up.  Still accept the case where size is now known.
		 Either the second copy may appear past the end of type or within
		 the non-POD buffer located inside the variably sized type
		 itself.  */
	      if (cur_offset != 0)
		goto no_useful_type_info;
	      /* If we determined type precisely or we have no clue on
 		 speuclation, we are done.  */
	      if (!maybe_derived_type || !speculative_outer_type
		  || !speculation_consistent_p (speculative_outer_type,
					        speculative_offset,
					        speculative_maybe_derived_type,
						otr_type))
		{
		  clear_speculation ();
	          return true;
		}
	      /* Otherwise look into speculation now.  */
	      else
		{
		  speculative = true;
		  type = speculative_outer_type;
		  cur_offset = speculative_offset;
		  continue;
		}
	    }
	}

      /* Walk fields and find corresponding on at OFFSET.  */
      if (TREE_CODE (type) == RECORD_TYPE)
	{
	  for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
	    {
	      if (TREE_CODE (fld) != FIELD_DECL
		  || TREE_TYPE (fld) == error_mark_node)
		continue;

	      pos = int_bit_position (fld);
	      if (pos > (unsigned HOST_WIDE_INT)cur_offset)
		continue;

	      /* Do not consider vptr itself.  Not even for placement new.  */
	      if (!pos && DECL_ARTIFICIAL (fld)
		  && POINTER_TYPE_P (TREE_TYPE (fld))
		  && TYPE_BINFO (type)
		  && polymorphic_type_binfo_p (TYPE_BINFO (type)))
		continue;

	      if (!DECL_SIZE (fld) || !tree_fits_uhwi_p (DECL_SIZE (fld)))
		goto no_useful_type_info;
	      size = tree_to_uhwi (DECL_SIZE (fld));

	      /* We can always skip types smaller than pointer size:
		 those can not contain a virtual table pointer.

		 Disqualifying fields that are too small to fit OTR_TYPE
		 saves work needed to walk them for no benefit.
		 Because of the way the bases are packed into a class, the
		 field's size may be smaller than type size, so it needs
		 to be done with a care.  */
		
	      if (pos <= (unsigned HOST_WIDE_INT)cur_offset
		  && (pos + size) >= (unsigned HOST_WIDE_INT)cur_offset
				     + POINTER_SIZE
		  && (!otr_type
		      || !TYPE_SIZE (TREE_TYPE (fld))
		      || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (fld)))
		      || (pos + tree_to_uhwi (TYPE_SIZE (TREE_TYPE (fld))))
			  >= cur_offset + otr_type_size))
		break;
	    }

	  if (!fld)
	    goto no_useful_type_info;

	  type = TYPE_MAIN_VARIANT (TREE_TYPE (fld));
	  cur_offset -= pos;
	  /* DECL_ARTIFICIAL represents a basetype.  */
	  if (!DECL_ARTIFICIAL (fld))
	    {
	      if (!speculative)
		{
		  outer_type = type;
		  offset = cur_offset;
		  /* As soon as we se an field containing the type,
		     we know we are not looking for derivations.  */
		  maybe_derived_type = false;
		}
	      else
		{
		  speculative_outer_type = type;
		  speculative_offset = cur_offset;
		  speculative_maybe_derived_type = false;
		}
	    }
	  else if (!consider_bases)
	    goto no_useful_type_info;
	}
      else if (TREE_CODE (type) == ARRAY_TYPE)
	{
	  tree subtype = TYPE_MAIN_VARIANT (TREE_TYPE (type));

	  /* Give up if we don't know array field size.
	     Also give up on non-polymorphic types as they are used
	     as buffers for placement new.  */
	  if (!TYPE_SIZE (subtype)
	      || !tree_fits_shwi_p (TYPE_SIZE (subtype))
	      || tree_to_shwi (TYPE_SIZE (subtype)) <= 0
	      || !contains_polymorphic_type_p (subtype))
	    goto no_useful_type_info;

	  HOST_WIDE_INT new_offset = cur_offset % tree_to_shwi (TYPE_SIZE (subtype));

	  /* We may see buffer for placement new.  In this case the expected type
	     can be bigger than the subtype.  */
	  if (TYPE_SIZE (subtype)
	      && (cur_offset + otr_type_size
		  > tree_to_uhwi (TYPE_SIZE (subtype))))
	    goto no_useful_type_info;

	  cur_offset = new_offset;
	  type = TYPE_MAIN_VARIANT (subtype);
	  if (!speculative)
	    {
	      outer_type = type;
	      offset = cur_offset;
	      maybe_derived_type = false;
	    }
	  else
	    {
	      speculative_outer_type = type;
	      speculative_offset = cur_offset;
	      speculative_maybe_derived_type = false;
	    }
	}
      /* Give up on anything else.  */
      else
	{
no_useful_type_info:
	  if (maybe_derived_type && !speculative
	      && TREE_CODE (outer_type) == RECORD_TYPE
	      && TREE_CODE (otr_type) == RECORD_TYPE
	      && TYPE_BINFO (otr_type)
	      && !offset
	      && get_binfo_at_offset (TYPE_BINFO (otr_type), 0, outer_type))
	    {
	      clear_outer_type (otr_type);
	      if (!speculative_outer_type
		  || !speculation_consistent_p (speculative_outer_type,
						speculative_offset,
					        speculative_maybe_derived_type,
						otr_type))
		clear_speculation ();
	      if (speculative_outer_type)
		{
		  speculative = true;
		  type = speculative_outer_type;
		  cur_offset = speculative_offset;
		}
	      else
		return true;
	    }
	  /* We found no way to embedd EXPECTED_TYPE in TYPE.
	     We still permit two special cases - placement new and
	     the case of variadic types containing themselves.  */
	  if (!speculative
	      && consider_placement_new
	      && (size_unknown || !type || maybe_derived_type
		  || possible_placement_new (type, otr_type, cur_offset)))
	    {
	      /* In these weird cases we want to accept the context.
		 In non-speculative run we have no useful outer_type info
		 (TODO: we may eventually want to record upper bound on the
		  type size that can be used to prune the walk),
		 but we still want to consider speculation that may
		 give useful info.  */
	      if (!speculative)
		{
		  clear_outer_type (otr_type);
		  if (!speculative_outer_type
		      || !speculation_consistent_p (speculative_outer_type,
						    speculative_offset,
						    speculative_maybe_derived_type,
						    otr_type))
		    clear_speculation ();
		  if (speculative_outer_type)
		    {
		      speculative = true;
		      type = speculative_outer_type;
		      cur_offset = speculative_offset;
		    }
		  else
		    return true;
		}
	      else
		{
		  clear_speculation ();
	          return true;
		}
	    }
	  else
	    {
	      clear_speculation ();
	      if (speculative)
		return true;
	      clear_outer_type (otr_type);
	      invalid = true; 
	      return false;
	    }
	}
    }
}

/* Return true if OUTER_TYPE contains OTR_TYPE at OFFSET.
   CONSIDER_PLACEMENT_NEW makes function to accept cases where OTR_TYPE can
   be built within OUTER_TYPE by means of placement new.  CONSIDER_BASES makes
   function to accept cases where OTR_TYPE appears as base of OUTER_TYPE or as
   base of one of fields of OUTER_TYPE.  */

static bool
contains_type_p (tree outer_type, HOST_WIDE_INT offset,
		 tree otr_type,
		 bool consider_placement_new,
		 bool consider_bases)
{
  ipa_polymorphic_call_context context;

  /* Check that type is within range.  */
  if (offset < 0)
    return false;

  /* PR ipa/71207
     As OUTER_TYPE can be a type which has a diamond virtual inheritance,
     it's not necessary that INNER_TYPE will fit within OUTER_TYPE with
     a given offset.  It can happen that INNER_TYPE also contains a base object,
     however it would point to the same instance in the OUTER_TYPE.  */

  context.offset = offset;
  context.outer_type = TYPE_MAIN_VARIANT (outer_type);
  context.maybe_derived_type = false;
  context.dynamic = false;
  return context.restrict_to_inner_class (otr_type, consider_placement_new,
					  consider_bases);
}


/* Return a FUNCTION_DECL if FN represent a constructor or destructor.
   If CHECK_CLONES is true, also check for clones of ctor/dtors.  */

tree
polymorphic_ctor_dtor_p (tree fn, bool check_clones)
{
  if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
      || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
    {
      if (!check_clones)
	return NULL_TREE;

      /* Watch for clones where we constant propagated the first
	 argument (pointer to the instance).  */
      fn = DECL_ABSTRACT_ORIGIN (fn);
      if (!fn
	  || TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
	  || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
	return NULL_TREE;
    }

  if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
    return NULL_TREE;

  return fn;
}

/* Return a FUNCTION_DECL if BLOCK represents a constructor or destructor.
   If CHECK_CLONES is true, also check for clones of ctor/dtors.  */

tree
inlined_polymorphic_ctor_dtor_block_p (tree block, bool check_clones)
{
  tree fn = block_ultimate_origin (block);
  if (fn == NULL || TREE_CODE (fn) != FUNCTION_DECL)
    return NULL_TREE;

  return polymorphic_ctor_dtor_p (fn, check_clones);
}


/* We know that the instance is stored in variable or parameter
   (not dynamically allocated) and we want to disprove the fact
   that it may be in construction at invocation of CALL.

   BASE represents memory location where instance is stored.
   If BASE is NULL, it is assumed to be global memory.
   OUTER_TYPE is known type of the instance or NULL if not
   known.

   For the variable to be in construction we actually need to
   be in constructor of corresponding global variable or
   the inline stack of CALL must contain the constructor.
   Check this condition.  This check works safely only before
   IPA passes, because inline stacks may become out of date
   later.  */

bool
decl_maybe_in_construction_p (tree base, tree outer_type,
			      gimple *call, tree function)
{
  if (outer_type)
    outer_type = TYPE_MAIN_VARIANT (outer_type);
  gcc_assert (!base || DECL_P (base));

  /* After inlining the code unification optimizations may invalidate
     inline stacks.  Also we need to give up on global variables after
     IPA, because addresses of these may have been propagated to their
     constructors.  */
  if (DECL_STRUCT_FUNCTION (function)->after_inlining)
    return true;

  /* Pure functions can not do any changes on the dynamic type;
     that require writting to memory.  */
  if ((!base || !auto_var_in_fn_p (base, function))
      && flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
    return false;

  bool check_clones = !base || is_global_var (base);
  for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
       block = BLOCK_SUPERCONTEXT (block))
    if (tree fn = inlined_polymorphic_ctor_dtor_block_p (block, check_clones))
      {
	tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn));

	if (!outer_type || !types_odr_comparable (type, outer_type))
	  {
	    if (TREE_CODE (type) == RECORD_TYPE
		&& TYPE_BINFO (type)
		&& polymorphic_type_binfo_p (TYPE_BINFO (type)))
	      return true;
	  }
 	else if (types_same_for_odr (type, outer_type))
	  return true;
      }

  if (!base || (VAR_P (base) && is_global_var (base)))
    {
      if (TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
	  || (!DECL_CXX_CONSTRUCTOR_P (function)
	      && !DECL_CXX_DESTRUCTOR_P (function)))
	{
	  if (!DECL_ABSTRACT_ORIGIN (function))
	    return false;
	  /* Watch for clones where we constant propagated the first
	     argument (pointer to the instance).  */
	  function = DECL_ABSTRACT_ORIGIN (function);
	  if (!function
	      || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE
	      || (!DECL_CXX_CONSTRUCTOR_P (function)
		  && !DECL_CXX_DESTRUCTOR_P (function)))
	    return false;
	}
      tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (function));
      if (!outer_type || !types_odr_comparable (type, outer_type))
	{
	  if (TREE_CODE (type) == RECORD_TYPE
	      && TYPE_BINFO (type)
	      && polymorphic_type_binfo_p (TYPE_BINFO (type)))
	    return true;
	}
      else if (types_same_for_odr (type, outer_type))
	return true;
    }
  return false;
}

/* Dump human readable context to F.  If NEWLINE is true, it will be terminated
   by a newline.  */

void
ipa_polymorphic_call_context::dump (FILE *f, bool newline) const
{
  fprintf (f, "    ");
  if (invalid)
    fprintf (f, "Call is known to be undefined");
  else
    {
      if (useless_p ())
	fprintf (f, "nothing known");
      if (outer_type || offset)
	{
	  fprintf (f, "Outer type%s:", dynamic ? " (dynamic)":"");
	  print_generic_expr (f, outer_type, TDF_SLIM);
	  if (maybe_derived_type)
	    fprintf (f, " (or a derived type)");
	  if (maybe_in_construction)
	    fprintf (f, " (maybe in construction)");
	  fprintf (f, " offset " HOST_WIDE_INT_PRINT_DEC,
		   offset);
	}
      if (speculative_outer_type)
	{
	  if (outer_type || offset)
	    fprintf (f, " ");
	  fprintf (f, "Speculative outer type:");
	  print_generic_expr (f, speculative_outer_type, TDF_SLIM);
	  if (speculative_maybe_derived_type)
	    fprintf (f, " (or a derived type)");
	  fprintf (f, " at offset " HOST_WIDE_INT_PRINT_DEC,
		   speculative_offset);
	}
    }
  if (newline)
    fprintf(f, "\n");
}

/* Print context to stderr.  */

void
ipa_polymorphic_call_context::debug () const
{
  dump (stderr);
}

/* Stream out the context to OB.  */

void
ipa_polymorphic_call_context::stream_out (struct output_block *ob) const
{
  struct bitpack_d bp = bitpack_create (ob->main_stream);

  bp_pack_value (&bp, invalid, 1);
  bp_pack_value (&bp, maybe_in_construction, 1);
  bp_pack_value (&bp, maybe_derived_type, 1);
  bp_pack_value (&bp, speculative_maybe_derived_type, 1);
  bp_pack_value (&bp, dynamic, 1);
  bp_pack_value (&bp, outer_type != NULL, 1);
  bp_pack_value (&bp, offset != 0, 1);
  bp_pack_value (&bp, speculative_outer_type != NULL, 1);
  streamer_write_bitpack (&bp);

  if (outer_type != NULL)
    stream_write_tree (ob, outer_type, true);
  if (offset)
    streamer_write_hwi (ob, offset);
  if (speculative_outer_type != NULL)
    {
      stream_write_tree (ob, speculative_outer_type, true);
      streamer_write_hwi (ob, speculative_offset);
    }
  else
    gcc_assert (!speculative_offset);
}

/* Stream in the context from IB and DATA_IN.  */

void
ipa_polymorphic_call_context::stream_in (struct lto_input_block *ib,
					 struct data_in *data_in)
{
  struct bitpack_d bp = streamer_read_bitpack (ib);

  invalid = bp_unpack_value (&bp, 1);
  maybe_in_construction = bp_unpack_value (&bp, 1);
  maybe_derived_type = bp_unpack_value (&bp, 1);
  speculative_maybe_derived_type = bp_unpack_value (&bp, 1);
  dynamic = bp_unpack_value (&bp, 1);
  bool outer_type_p = bp_unpack_value (&bp, 1);
  bool offset_p = bp_unpack_value (&bp, 1);
  bool speculative_outer_type_p = bp_unpack_value (&bp, 1);

  if (outer_type_p)
    outer_type = stream_read_tree (ib, data_in);
  else
    outer_type = NULL;
  if (offset_p)
    offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
  else
    offset = 0;
  if (speculative_outer_type_p)
    {
      speculative_outer_type = stream_read_tree (ib, data_in);
      speculative_offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
    }
  else
    {
      speculative_outer_type = NULL;
      speculative_offset = 0;
    }
}

/* Proudce polymorphic call context for call method of instance
   that is located within BASE (that is assumed to be a decl) at offset OFF. */

void
ipa_polymorphic_call_context::set_by_decl (tree base, HOST_WIDE_INT off)
{
  gcc_assert (DECL_P (base));
  clear_speculation ();

  if (!contains_polymorphic_type_p (TREE_TYPE (base)))
    {
      clear_outer_type ();
      offset = off;
      return;
    }
  outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (base));
  offset = off;
  /* Make very conservative assumption that all objects
     may be in construction. 
 
     It is up to caller to revisit this via
     get_dynamic_type or decl_maybe_in_construction_p.  */
  maybe_in_construction = true;
  maybe_derived_type = false;
  dynamic = false;
}

/* CST is an invariant (address of decl), try to get meaningful
   polymorphic call context for polymorphic call of method 
   if instance of OTR_TYPE that is located at offset OFF of this invariant.
   Return FALSE if nothing meaningful can be found.  */

bool
ipa_polymorphic_call_context::set_by_invariant (tree cst,
						tree otr_type,
						HOST_WIDE_INT off)
{
  poly_int64 offset2, size, max_size;
  bool reverse;
  tree base;

  invalid = false;
  off = 0;
  clear_outer_type (otr_type);

  if (TREE_CODE (cst) != ADDR_EXPR)
    return false;

  cst = TREE_OPERAND (cst, 0);
  base = get_ref_base_and_extent (cst, &offset2, &size, &max_size, &reverse);
  if (!DECL_P (base) || !known_size_p (max_size) || maybe_ne (max_size, size))
    return false;

  /* Only type inconsistent programs can have otr_type that is
     not part of outer type.  */
  if (otr_type && !contains_type_p (TREE_TYPE (base), off, otr_type))
    return false;

  set_by_decl (base, off);
  return true;
}

/* See if OP is SSA name initialized as a copy or by single assignment.
   If so, walk the SSA graph up.  Because simple PHI conditional is considered
   copy, GLOBAL_VISITED may be used to avoid infinite loop walking the SSA
   graph.  */

static tree
walk_ssa_copies (tree op, hash_set<tree> **global_visited = NULL)
{
  hash_set <tree> *visited = NULL;
  STRIP_NOPS (op);
  while (TREE_CODE (op) == SSA_NAME
	 && !SSA_NAME_IS_DEFAULT_DEF (op)
	 /* We might be called via fold_stmt during cfgcleanup where
	    SSA form need not be up-to-date.  */
	 && !name_registered_for_update_p (op) 
	 && (gimple_assign_single_p (SSA_NAME_DEF_STMT (op))
	     || gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI))
    {
      if (global_visited)
	{
	  if (!*global_visited)
	    *global_visited = new hash_set<tree>;
	  if ((*global_visited)->add (op))
	    goto done;
	}	
      else
	{
	  if (!visited)
	    visited = new hash_set<tree>;
	  if (visited->add (op))
	    goto done;
	}
      /* Special case
	 if (ptr == 0)
	   ptr = 0;
	 else
	   ptr = ptr.foo;
	 This pattern is implicitly produced for casts to non-primary
	 bases.  When doing context analysis, we do not really care
	 about the case pointer is NULL, because the call will be
	 undefined anyway.  */
      if (gimple_code (SSA_NAME_DEF_STMT (op)) == GIMPLE_PHI)
	{
	  gimple *phi = SSA_NAME_DEF_STMT (op);

	  if (gimple_phi_num_args (phi) > 2)
	    goto done;
	  if (gimple_phi_num_args (phi) == 1)
	    op = gimple_phi_arg_def (phi, 0);
	  else if (integer_zerop (gimple_phi_arg_def (phi, 0)))
	    op = gimple_phi_arg_def (phi, 1);
	  else if (integer_zerop (gimple_phi_arg_def (phi, 1)))
	    op = gimple_phi_arg_def (phi, 0);
	  else
	    goto done;
	}
      else
	{
	  if (gimple_assign_load_p (SSA_NAME_DEF_STMT (op)))
	    goto done;
	  op = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op));
	}
      STRIP_NOPS (op);
    }
done:
  if (visited)
    delete (visited);
  return op;
}

/* Create polymorphic call context from IP invariant CST.
   This is typically &global_var.
   OTR_TYPE specify type of polymorphic call or NULL if unknown, OFF
   is offset of call.  */

ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree cst,
							    tree otr_type,
							    HOST_WIDE_INT off)
{
  clear_speculation ();
  set_by_invariant (cst, otr_type, off);
}

/* Build context for pointer REF contained in FNDECL at statement STMT.
   if INSTANCE is non-NULL, return pointer to the object described by
   the context or DECL where context is contained in.  */

ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl,
							    tree ref,
							    gimple *stmt,
							    tree *instance)
{
  tree otr_type = NULL;
  tree base_pointer;
  hash_set <tree> *visited = NULL;

  if (TREE_CODE (ref) == OBJ_TYPE_REF)
    {
      otr_type = obj_type_ref_class (ref);
      base_pointer = OBJ_TYPE_REF_OBJECT (ref);
    }
  else
    base_pointer = ref;

  /* Set up basic info in case we find nothing interesting in the analysis.  */
  clear_speculation ();
  clear_outer_type (otr_type);
  invalid = false;

  /* Walk SSA for outer object.  */
  while (true)
    {
      base_pointer = walk_ssa_copies (base_pointer, &visited);
      if (TREE_CODE (base_pointer) == ADDR_EXPR)
	{
	  HOST_WIDE_INT offset2, size;
	  bool reverse;
	  tree base
	    = get_ref_base_and_extent_hwi (TREE_OPERAND (base_pointer, 0),
					   &offset2, &size, &reverse);
	  if (!base)
	    break;

	  combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)),
				    offset + offset2,
				    true,
				    NULL /* Do not change outer type.  */);

	  /* If this is a varying address, punt.  */
	  if (TREE_CODE (base) == MEM_REF || DECL_P (base))
	    {
	      /* We found dereference of a pointer.  Type of the pointer
		 and MEM_REF is meaningless, but we can look futher.  */
	      offset_int mem_offset;
	      if (TREE_CODE (base) == MEM_REF
		  && mem_ref_offset (base).is_constant (&mem_offset))
		{
		  offset_int o = mem_offset * BITS_PER_UNIT;
		  o += offset;
		  o += offset2;
		  if (!wi::fits_shwi_p (o))
		    break;
		  base_pointer = TREE_OPERAND (base, 0);
		  offset = o.to_shwi ();
		  outer_type = NULL;
		}
	      /* We found base object.  In this case the outer_type
		 is known.  */
	      else if (DECL_P (base))
		{
		  if (visited)
		    delete (visited);
		  /* Only type inconsistent programs can have otr_type that is
		     not part of outer type.  */
		  if (otr_type
		      && !contains_type_p (TREE_TYPE (base),
					   offset + offset2, otr_type))
		    {
		      invalid = true;
		      if (instance)
			*instance = base_pointer;
		      return;
		    }
		  set_by_decl (base, offset + offset2);
		  if (outer_type && maybe_in_construction && stmt)
		    maybe_in_construction
		     = decl_maybe_in_construction_p (base,
						     outer_type,
						     stmt,
						     fndecl);
		  if (instance)
		    *instance = base;
		  return;
		}
	      else
		break;
	    }
	  else
	    break;
	}
      else if (TREE_CODE (base_pointer) == POINTER_PLUS_EXPR
	       && TREE_CODE (TREE_OPERAND (base_pointer, 1)) == INTEGER_CST)
	{
	  offset_int o
	    = offset_int::from (wi::to_wide (TREE_OPERAND (base_pointer, 1)),
				SIGNED);
	  o *= BITS_PER_UNIT;
	  o += offset;
	  if (!wi::fits_shwi_p (o))
	    break;
	  offset = o.to_shwi ();
	  base_pointer = TREE_OPERAND (base_pointer, 0);
	}
      else
	break;
    }

  if (visited)
    delete (visited);

  /* Try to determine type of the outer object.  */
  if (TREE_CODE (base_pointer) == SSA_NAME
      && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
      && TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL)
    {
      /* See if parameter is THIS pointer of a method.  */
      if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE
	  && SSA_NAME_VAR (base_pointer) == DECL_ARGUMENTS (fndecl))
	{
	  outer_type
	     = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
	  gcc_assert (TREE_CODE (outer_type) == RECORD_TYPE
		      || TREE_CODE (outer_type) == UNION_TYPE);

	  /* Dynamic casting has possibly upcasted the type
	     in the hiearchy.  In this case outer type is less
	     informative than inner type and we should forget
	     about it.  */
	  if ((otr_type
	       && !contains_type_p (outer_type, offset,
				    otr_type))
	      || !contains_polymorphic_type_p (outer_type))
	    {
	      outer_type = NULL;
	      if (instance)
		*instance = base_pointer;
	      return;
	    }

	  dynamic = true;

	  /* If the function is constructor or destructor, then
	     the type is possibly in construction, but we know
	     it is not derived type.  */
	  if (DECL_CXX_CONSTRUCTOR_P (fndecl)
	      || DECL_CXX_DESTRUCTOR_P (fndecl))
	    {
	      maybe_in_construction = true;
	      maybe_derived_type = false;
	    }
	  else
	    {
	      maybe_derived_type = true;
	      maybe_in_construction = false;
	    }
	  if (instance)
	    *instance = base_pointer;
	  return;
	}
      /* Non-PODs passed by value are really passed by invisible
	 reference.  In this case we also know the type of the
	 object.  */
      if (DECL_BY_REFERENCE (SSA_NAME_VAR (base_pointer)))
	{
	  outer_type
	     = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer)));
	  /* Only type inconsistent programs can have otr_type that is
	     not part of outer type.  */
	  if (otr_type && !contains_type_p (outer_type, offset,
					    otr_type))
	    { 
	      invalid = true;
	      if (instance)
		*instance = base_pointer;
	      return;
	    }
	  /* Non-polymorphic types have no interest for us.  */
	  else if (!otr_type && !contains_polymorphic_type_p (outer_type))
	    {
	      outer_type = NULL;
	      if (instance)
		*instance = base_pointer;
	      return;
	    }
	  maybe_derived_type = false;
	  maybe_in_construction = false;
	  if (instance)
	    *instance = base_pointer;
	  return;
	}
    }

  tree base_type = TREE_TYPE (base_pointer);

  if (TREE_CODE (base_pointer) == SSA_NAME
      && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
      && !(TREE_CODE (SSA_NAME_VAR (base_pointer)) == PARM_DECL
	   || TREE_CODE (SSA_NAME_VAR (base_pointer)) == RESULT_DECL))
    {
      invalid = true;
      if (instance)
	*instance = base_pointer;
      return;
    }
  if (TREE_CODE (base_pointer) == SSA_NAME
      && SSA_NAME_DEF_STMT (base_pointer)
      && gimple_assign_single_p (SSA_NAME_DEF_STMT (base_pointer)))
    base_type = TREE_TYPE (gimple_assign_rhs1
			    (SSA_NAME_DEF_STMT (base_pointer)));
 
  if (base_type && POINTER_TYPE_P (base_type))
    combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base_type)),
			      offset,
			      true, NULL /* Do not change type here */);
  /* TODO: There are multiple ways to derive a type.  For instance
     if BASE_POINTER is passed to an constructor call prior our refernece.
     We do not make this type of flow sensitive analysis yet.  */
  if (instance)
    *instance = base_pointer;
  return;
}

/* Structure to be passed in between detect_type_change and
   check_stmt_for_type_change.  */

struct type_change_info
{
  /* Offset into the object where there is the virtual method pointer we are
     looking for.  */
  HOST_WIDE_INT offset;
  /* The declaration or SSA_NAME pointer of the base that we are checking for
     type change.  */
  tree instance;
  /* The reference to virtual table pointer used.  */
  tree vtbl_ptr_ref;
  tree otr_type;
  /* If we actually can tell the type that the object has changed to, it is
     stored in this field.  Otherwise it remains NULL_TREE.  */
  tree known_current_type;
  HOST_WIDE_INT known_current_offset;

  /* Set to nonzero if we possibly missed some dynamic type changes and we
     should consider the set to be speculative.  */
  unsigned speculative;

  /* Set to true if dynamic type change has been detected.  */
  bool type_maybe_changed;
  /* Set to true if multiple types have been encountered.  known_current_type
     must be disregarded in that case.  */
  bool multiple_types_encountered;
  bool seen_unanalyzed_store;
};

/* Return true if STMT is not call and can modify a virtual method table pointer.
   We take advantage of fact that vtable stores must appear within constructor
   and destructor functions.  */

static bool
noncall_stmt_may_be_vtbl_ptr_store (gimple *stmt)
{
  if (is_gimple_assign (stmt))
    {
      tree lhs = gimple_assign_lhs (stmt);

      if (gimple_clobber_p (stmt))
	return false;
      if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
	{
	  if (flag_strict_aliasing
	      && !POINTER_TYPE_P (TREE_TYPE (lhs)))
	    return false;

	  if (TREE_CODE (lhs) == COMPONENT_REF
	      && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
	    return false;
	  /* In the future we might want to use get_ref_base_and_extent to find
	     if there is a field corresponding to the offset and if so, proceed
	     almost like if it was a component ref.  */
	}
    }

  /* Code unification may mess with inline stacks.  */
  if (cfun->after_inlining)
    return true;

  /* Walk the inline stack and watch out for ctors/dtors.
     TODO: Maybe we can require the store to appear in toplevel
     block of CTOR/DTOR.  */
  for (tree block = gimple_block (stmt); block && TREE_CODE (block) == BLOCK;
       block = BLOCK_SUPERCONTEXT (block))
    if (BLOCK_ABSTRACT_ORIGIN (block)
	&& TREE_CODE (block_ultimate_origin (block)) == FUNCTION_DECL)
      return inlined_polymorphic_ctor_dtor_block_p (block, false);
  return (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
	  && (DECL_CXX_CONSTRUCTOR_P (current_function_decl)
	      || DECL_CXX_DESTRUCTOR_P (current_function_decl)));
}

/* If STMT can be proved to be an assignment to the virtual method table
   pointer of ANALYZED_OBJ and the type associated with the new table
   identified, return the type.  Otherwise return NULL_TREE if type changes
   in unknown way or ERROR_MARK_NODE if type is unchanged.  */

static tree
extr_type_from_vtbl_ptr_store (gimple *stmt, struct type_change_info *tci,
			       HOST_WIDE_INT *type_offset)
{
  poly_int64 offset, size, max_size;
  tree lhs, rhs, base;
  bool reverse;

  if (!gimple_assign_single_p (stmt))
    return NULL_TREE;

  lhs = gimple_assign_lhs (stmt);
  rhs = gimple_assign_rhs1 (stmt);
  if (TREE_CODE (lhs) != COMPONENT_REF
      || !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
     {
	if (dump_file)
	  fprintf (dump_file, "  LHS is not virtual table.\n");
	return NULL_TREE;
     }

  if (tci->vtbl_ptr_ref && operand_equal_p (lhs, tci->vtbl_ptr_ref, 0))
    ;
  else
    {
      base = get_ref_base_and_extent (lhs, &offset, &size, &max_size, &reverse);
      if (DECL_P (tci->instance))
	{
	  if (base != tci->instance)
	    {
	      if (dump_file)
		{
		  fprintf (dump_file, "    base:");
		  print_generic_expr (dump_file, base, TDF_SLIM);
		  fprintf (dump_file, " does not match instance:");
		  print_generic_expr (dump_file, tci->instance, TDF_SLIM);
		  fprintf (dump_file, "\n");
		}
	      return NULL_TREE;
	    }
	}
      else if (TREE_CODE (base) == MEM_REF)
	{
	  if (!operand_equal_p (tci->instance, TREE_OPERAND (base, 0), 0))
	    {
	      if (dump_file)
		{
		  fprintf (dump_file, "    base mem ref:");
		  print_generic_expr (dump_file, base, TDF_SLIM);
		  fprintf (dump_file, " does not match instance:");
		  print_generic_expr (dump_file, tci->instance, TDF_SLIM);
		  fprintf (dump_file, "\n");
		}
	      return NULL_TREE;
	    }
	  if (!integer_zerop (TREE_OPERAND (base, 1)))
	    {
	      if (!tree_fits_shwi_p (TREE_OPERAND (base, 1)))
		{
		  if (dump_file)
		    {
		      fprintf (dump_file, "    base mem ref:");
		      print_generic_expr (dump_file, base, TDF_SLIM);
		      fprintf (dump_file, " has non-representable offset:");
		      print_generic_expr (dump_file, tci->instance, TDF_SLIM);
		      fprintf (dump_file, "\n");
		    }
		  return NULL_TREE;
		}
	      else
	        offset += tree_to_shwi (TREE_OPERAND (base, 1)) * BITS_PER_UNIT;
	    }
	}
      else if (!operand_equal_p (tci->instance, base, 0)
	       || tci->offset)
	{
	  if (dump_file)
	    {
	      fprintf (dump_file, "    base:");
	      print_generic_expr (dump_file, base, TDF_SLIM);
	      fprintf (dump_file, " does not match instance:");
	      print_generic_expr (dump_file, tci->instance, TDF_SLIM);
	      fprintf (dump_file, " with offset %i\n", (int)tci->offset);
	    }
	  return tci->offset > POINTER_SIZE ? error_mark_node : NULL_TREE;
	}
      if (maybe_ne (offset, tci->offset)
	  || maybe_ne (size, POINTER_SIZE)
	  || maybe_ne (max_size, POINTER_SIZE))
	{
	  if (dump_file)
	    {
	      fprintf (dump_file, "    wrong offset ");
	      print_dec (offset, dump_file);
	      fprintf (dump_file, "!=%i or size ", (int) tci->offset);
	      print_dec (size, dump_file);
	      fprintf (dump_file, "\n");
	    }
	  return (known_le (offset + POINTER_SIZE, tci->offset)
		  || (known_size_p (max_size)
		      && known_gt (tci->offset + POINTER_SIZE,
				   offset + max_size))
		  ? error_mark_node : NULL);
	}
    }

  tree vtable;
  unsigned HOST_WIDE_INT offset2;

  if (!vtable_pointer_value_to_vtable (rhs, &vtable, &offset2))
    {
      if (dump_file)
	fprintf (dump_file, "    Failed to lookup binfo\n");
      return NULL;
    }

  tree binfo = subbinfo_with_vtable_at_offset (TYPE_BINFO (DECL_CONTEXT (vtable)),
					       offset2, vtable);
  if (!binfo)
    {
      if (dump_file)
	fprintf (dump_file, "    Construction vtable used\n");
      /* FIXME: We should suport construction contexts.  */
      return NULL;
    }
 
  *type_offset = tree_to_shwi (BINFO_OFFSET (binfo)) * BITS_PER_UNIT;
  return DECL_CONTEXT (vtable);
}

/* Record dynamic type change of TCI to TYPE.  */

static void
record_known_type (struct type_change_info *tci, tree type, HOST_WIDE_INT offset)
{
  if (dump_file)
    {
      if (type)
	{
          fprintf (dump_file, "  Recording type: ");
	  print_generic_expr (dump_file, type, TDF_SLIM);
          fprintf (dump_file, " at offset %i\n", (int)offset);
	}
     else
       fprintf (dump_file, "  Recording unknown type\n");
    }

  /* If we found a constructor of type that is not polymorphic or
     that may contain the type in question as a field (not as base),
     restrict to the inner class first to make type matching bellow
     happier.  */
  if (type
      && (offset
          || (TREE_CODE (type) != RECORD_TYPE
	      || !TYPE_BINFO (type)
	      || !polymorphic_type_binfo_p (TYPE_BINFO (type)))))
    {
      ipa_polymorphic_call_context context;

      context.offset = offset;
      context.outer_type = type;
      context.maybe_in_construction = false;
      context.maybe_derived_type = false;
      context.dynamic = true;
      /* If we failed to find the inner type, we know that the call
	 would be undefined for type produced here.  */
      if (!context.restrict_to_inner_class (tci->otr_type))
	{
	  if (dump_file)
	    fprintf (dump_file, "  Ignoring; does not contain otr_type\n");
	  return;
	}
      /* Watch for case we reached an POD type and anticipate placement
	 new.  */
      if (!context.maybe_derived_type)
	{
          type = context.outer_type;
          offset = context.offset;
	}
    }
  if (tci->type_maybe_changed
      && (!types_same_for_odr (type, tci->known_current_type)
	  || offset != tci->known_current_offset))
    tci->multiple_types_encountered = true;
  tci->known_current_type = TYPE_MAIN_VARIANT (type);
  tci->known_current_offset = offset;
  tci->type_maybe_changed = true;
}


/* The maximum number of may-defs we visit when looking for a must-def
   that changes the dynamic type in check_stmt_for_type_change.  Tuned
   after the PR12392 testcase which unlimited spends 40% time within
   these alias walks and 8% with the following limit.  */

static inline bool
csftc_abort_walking_p (unsigned speculative)
{
  unsigned max = PARAM_VALUE (PARAM_MAX_SPECULATIVE_DEVIRT_MAYDEFS);
  return speculative > max ? true : false;
}

/* Callback of walk_aliased_vdefs and a helper function for
   detect_type_change to check whether a particular statement may modify
   the virtual table pointer, and if possible also determine the new type of
   the (sub-)object.  It stores its result into DATA, which points to a
   type_change_info structure.  */

static bool
check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
{
  gimple *stmt = SSA_NAME_DEF_STMT (vdef);
  struct type_change_info *tci = (struct type_change_info *) data;
  tree fn;

  /* If we already gave up, just terminate the rest of walk.  */
  if (tci->multiple_types_encountered)
    return true;

  if (is_gimple_call (stmt))
    {
      if (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))
	return false;

      /* Check for a constructor call.  */
      if ((fn = gimple_call_fndecl (stmt)) != NULL_TREE
	  && DECL_CXX_CONSTRUCTOR_P (fn)
	  && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
	  && gimple_call_num_args (stmt))
      {
	tree op = walk_ssa_copies (gimple_call_arg (stmt, 0));
	tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
	HOST_WIDE_INT offset = 0;
	bool reverse;

	if (dump_file)
	  {
	    fprintf (dump_file, "  Checking constructor call: ");
	    print_gimple_stmt (dump_file, stmt, 0);
	  }

	/* See if THIS parameter seems like instance pointer.  */
	if (TREE_CODE (op) == ADDR_EXPR)
	  {
	    HOST_WIDE_INT size;
	    op = get_ref_base_and_extent_hwi (TREE_OPERAND (op, 0),
					      &offset, &size, &reverse);
	    if (!op)
	      {
                tci->speculative++;
	        return csftc_abort_walking_p (tci->speculative);
	      }
	    if (TREE_CODE (op) == MEM_REF)
	      {
		if (!tree_fits_shwi_p (TREE_OPERAND (op, 1)))
		  {
                    tci->speculative++;
		    return csftc_abort_walking_p (tci->speculative);
		  }
		offset += tree_to_shwi (TREE_OPERAND (op, 1))
			  * BITS_PER_UNIT;
		op = TREE_OPERAND (op, 0);
	      }
	    else if (DECL_P (op))
	      ;
	    else
	      {
                tci->speculative++;
	        return csftc_abort_walking_p (tci->speculative);
	      }
	    op = walk_ssa_copies (op);
	  }
	if (operand_equal_p (op, tci->instance, 0)
	    && TYPE_SIZE (type)
	    && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
	    && tree_fits_shwi_p (TYPE_SIZE (type))
	    && tree_to_shwi (TYPE_SIZE (type)) + offset > tci->offset
	    /* Some inlined constructors may look as follows:
		  _3 = operator new (16);
		  MEM[(struct  &)_3] ={v} {CLOBBER};
		  MEM[(struct CompositeClass *)_3]._vptr.CompositeClass
		    = &MEM[(void *)&_ZTV14CompositeClass + 16B];
		  _7 = &MEM[(struct CompositeClass *)_3].object;
		  EmptyClass::EmptyClass (_7);

	       When determining dynamic type of _3 and because we stop at first
	       dynamic type found, we would stop on EmptyClass::EmptyClass (_7).
	       In this case the emptyclass is not even polymorphic and we miss
	       it is contained in an outer type that is polymorphic.  */

	    && (tci->offset == offset || contains_polymorphic_type_p (type)))
	  {
	    record_known_type (tci, type, tci->offset - offset);
	    return true;
	  }
      }
     /* Calls may possibly change dynamic type by placement new. Assume
        it will not happen, but make result speculative only.  */
     if (dump_file)
	{
          fprintf (dump_file, "  Function call may change dynamic type:");
	  print_gimple_stmt (dump_file, stmt, 0);
	}
     tci->speculative++;
     return csftc_abort_walking_p (tci->speculative);
   }
  /* Check for inlined virtual table store.  */
  else if (noncall_stmt_may_be_vtbl_ptr_store (stmt))
    {
      tree type;
      HOST_WIDE_INT offset = 0;
      if (dump_file)
	{
	  fprintf (dump_file, "  Checking vtbl store: ");
	  print_gimple_stmt (dump_file, stmt, 0);
	}

      type = extr_type_from_vtbl_ptr_store (stmt, tci, &offset);
      if (type == error_mark_node)
	return false;
      gcc_assert (!type || TYPE_MAIN_VARIANT (type) == type);
      if (!type)
	{
	  if (dump_file)
	    fprintf (dump_file, "  Unanalyzed store may change type.\n");
	  tci->seen_unanalyzed_store = true;
	  tci->speculative++;
	}
      else
        record_known_type (tci, type, offset);
      return true;
    }
  else
    return false;
}

/* THIS is polymorphic call context obtained from get_polymorphic_context.
   OTR_OBJECT is pointer to the instance returned by OBJ_TYPE_REF_OBJECT.
   INSTANCE is pointer to the outer instance as returned by
   get_polymorphic_context.  To avoid creation of temporary expressions,
   INSTANCE may also be an declaration of get_polymorphic_context found the
   value to be in static storage.

   If the type of instance is not fully determined
   (either OUTER_TYPE is unknown or MAYBE_IN_CONSTRUCTION/INCLUDE_DERIVED_TYPES
   is set), try to walk memory writes and find the actual construction of the
   instance.

   Return true if memory is unchanged from function entry.

   We do not include this analysis in the context analysis itself, because
   it needs memory SSA to be fully built and the walk may be expensive.
   So it is not suitable for use withing fold_stmt and similar uses.  */

bool
ipa_polymorphic_call_context::get_dynamic_type (tree instance,
						tree otr_object,
						tree otr_type,
						gimple *call)
{
  struct type_change_info tci;
  ao_ref ao;
  bool function_entry_reached = false;
  tree instance_ref = NULL;
  gimple *stmt = call;
  /* Remember OFFSET before it is modified by restrict_to_inner_class.
     This is because we do not update INSTANCE when walking inwards.  */
  HOST_WIDE_INT instance_offset = offset;
  tree instance_outer_type = outer_type;

  if (otr_type)
    otr_type = TYPE_MAIN_VARIANT (otr_type);

  /* Walk into inner type. This may clear maybe_derived_type and save us
     from useless work.  It also makes later comparsions with static type
     easier.  */
  if (outer_type && otr_type)
    {
      if (!restrict_to_inner_class (otr_type))
        return false;
    }

  if (!maybe_in_construction && !maybe_derived_type)
    return false;

  /* If we are in fact not looking at any object object or the instance is
     some placement new into a random load, give up straight away.  */
  if (TREE_CODE (instance) == MEM_REF)
    return false;

  /* We need to obtain refernce to virtual table pointer.  It is better
     to look it up in the code rather than build our own.  This require bit
     of pattern matching, but we end up verifying that what we found is
     correct. 

     What we pattern match is:

       tmp = instance->_vptr.A;   // vtbl ptr load
       tmp2 = tmp[otr_token];	  // vtable lookup
       OBJ_TYPE_REF(tmp2;instance->0) (instance);
 
     We want to start alias oracle walk from vtbl pointer load,
     but we may not be able to identify it, for example, when PRE moved the
     load around.  */

  if (gimple_code (call) == GIMPLE_CALL)
    {
      tree ref = gimple_call_fn (call);
      bool reverse;

      if (TREE_CODE (ref) == OBJ_TYPE_REF)
	{
	  ref = OBJ_TYPE_REF_EXPR (ref);
	  ref = walk_ssa_copies (ref);

	  /* If call target is already known, no need to do the expensive
 	     memory walk.  */
	  if (is_gimple_min_invariant (ref))
	    return false;

	  /* Check if definition looks like vtable lookup.  */
	  if (TREE_CODE (ref) == SSA_NAME
	      && !SSA_NAME_IS_DEFAULT_DEF (ref)
	      && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref))
	      && TREE_CODE (gimple_assign_rhs1
			     (SSA_NAME_DEF_STMT (ref))) == MEM_REF)
	    {
	      ref = get_base_address
		     (TREE_OPERAND (gimple_assign_rhs1
				     (SSA_NAME_DEF_STMT (ref)), 0));
	      ref = walk_ssa_copies (ref);
	      /* Find base address of the lookup and see if it looks like
		 vptr load.  */
	      if (TREE_CODE (ref) == SSA_NAME
		  && !SSA_NAME_IS_DEFAULT_DEF (ref)
		  && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref)))
		{
		  HOST_WIDE_INT offset2, size;
		  tree ref_exp = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (ref));
		  tree base_ref
		    = get_ref_base_and_extent_hwi (ref_exp, &offset2,
						   &size, &reverse);

		  /* Finally verify that what we found looks like read from
		     OTR_OBJECT or from INSTANCE with offset OFFSET.  */
		  if (base_ref
		      && ((TREE_CODE (base_ref) == MEM_REF
		           && ((offset2 == instance_offset
		                && TREE_OPERAND (base_ref, 0) == instance)
			       || (!offset2
				   && TREE_OPERAND (base_ref, 0)
				      == otr_object)))
			  || (DECL_P (instance) && base_ref == instance
			      && offset2 == instance_offset)))
		    {
		      stmt = SSA_NAME_DEF_STMT (ref);
		      instance_ref = ref_exp;
		    }
		}
	    }
	}
    }
 
  /* If we failed to look up the reference in code, build our own.  */
  if (!instance_ref)
    {
      /* If the statement in question does not use memory, we can't tell
	 anything.  */
      if (!gimple_vuse (stmt))
	return false;
      ao_ref_init_from_ptr_and_size (&ao, otr_object, NULL);
    }
  else
  /* Otherwise use the real reference.  */
    ao_ref_init (&ao, instance_ref);

  /* We look for vtbl pointer read.  */
  ao.size = POINTER_SIZE;
  ao.max_size = ao.size;
  /* We are looking for stores to vptr pointer within the instance of
     outer type.
     TODO: The vptr pointer type is globally known, we probably should
     keep it and do that even when otr_type is unknown.  */
  if (otr_type)
    {
      ao.base_alias_set
	= get_alias_set (outer_type ? outer_type : otr_type);
      ao.ref_alias_set
        = get_alias_set (TREE_TYPE (BINFO_VTABLE (TYPE_BINFO (otr_type))));
    }

  if (dump_file)
    {
      fprintf (dump_file, "Determining dynamic type for call: ");
      print_gimple_stmt (dump_file, call, 0);
      fprintf (dump_file, "  Starting walk at: ");
      print_gimple_stmt (dump_file, stmt, 0);
      fprintf (dump_file, "  instance pointer: ");
      print_generic_expr (dump_file, otr_object, TDF_SLIM);
      fprintf (dump_file, "  Outer instance pointer: ");
      print_generic_expr (dump_file, instance, TDF_SLIM);
      fprintf (dump_file, " offset: %i (bits)", (int)instance_offset);
      fprintf (dump_file, " vtbl reference: ");
      print_generic_expr (dump_file, instance_ref, TDF_SLIM);
      fprintf (dump_file, "\n");
    }

  tci.offset = instance_offset;
  tci.instance = instance;
  tci.vtbl_ptr_ref = instance_ref;
  tci.known_current_type = NULL_TREE;
  tci.known_current_offset = 0;
  tci.otr_type = otr_type;
  tci.type_maybe_changed = false;
  tci.multiple_types_encountered = false;
  tci.speculative = 0;
  tci.seen_unanalyzed_store = false;

  walk_aliased_vdefs (&ao, gimple_vuse (stmt), check_stmt_for_type_change,
		      &tci, NULL, &function_entry_reached);

  /* If we did not find any type changing statements, we may still drop
     maybe_in_construction flag if the context already have outer type. 

     Here we make special assumptions about both constructors and
     destructors which are all the functions that are allowed to alter the
     VMT pointers.  It assumes that destructors begin with assignment into
     all VMT pointers and that constructors essentially look in the
     following way:

     1) The very first thing they do is that they call constructors of
     ancestor sub-objects that have them.

     2) Then VMT pointers of this and all its ancestors is set to new
     values corresponding to the type corresponding to the constructor.

     3) Only afterwards, other stuff such as constructor of member
     sub-objects and the code written by the user is run.  Only this may
     include calling virtual functions, directly or indirectly.

     4) placement new can not be used to change type of non-POD statically
     allocated variables.

     There is no way to call a constructor of an ancestor sub-object in any
     other way.

     This means that we do not have to care whether constructors get the
     correct type information because they will always change it (in fact,
     if we define the type to be given by the VMT pointer, it is undefined).

     The most important fact to derive from the above is that if, for some
     statement in the section 3, we try to detect whether the dynamic type
     has changed, we can safely ignore all calls as we examine the function
     body backwards until we reach statements in section 2 because these
     calls cannot be ancestor constructors or destructors (if the input is
     not bogus) and so do not change the dynamic type (this holds true only
     for automatically allocated objects but at the moment we devirtualize
     only these).  We then must detect that statements in section 2 change
     the dynamic type and can try to derive the new type.  That is enough
     and we can stop, we will never see the calls into constructors of
     sub-objects in this code. 

     Therefore if the static outer type was found (outer_type)
     we can safely ignore tci.speculative that is set on calls and give up
     only if there was dyanmic type store that may affect given variable
     (seen_unanalyzed_store)  */

  if (!tci.type_maybe_changed
      || (outer_type
	  && !dynamic
	  && !tci.seen_unanalyzed_store
	  && !tci.multiple_types_encountered
	  && ((offset == tci.offset
	       && types_same_for_odr (tci.known_current_type,
				      outer_type))
	       || (instance_offset == offset
		   && types_same_for_odr (tci.known_current_type,
					  instance_outer_type)))))
    {
      if (!outer_type || tci.seen_unanalyzed_store)
	return false;
      if (maybe_in_construction)
        maybe_in_construction = false;
      if (dump_file)
	fprintf (dump_file, "  No dynamic type change found.\n");
      return true;
    }

  if (tci.known_current_type
      && !function_entry_reached
      && !tci.multiple_types_encountered)
    {
      if (!tci.speculative)
	{
	  outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
	  offset = tci.known_current_offset;
	  dynamic = true;
	  maybe_in_construction = false;
	  maybe_derived_type = false;
	  if (dump_file)
	    fprintf (dump_file, "  Determined dynamic type.\n");
	}
      else if (!speculative_outer_type
	       || speculative_maybe_derived_type)
	{
	  speculative_outer_type = TYPE_MAIN_VARIANT (tci.known_current_type);
	  speculative_offset = tci.known_current_offset;
	  speculative_maybe_derived_type = false;
	  if (dump_file)
	    fprintf (dump_file, "  Determined speculative dynamic type.\n");
	}
    }
  else if (dump_file)
    {
      fprintf (dump_file, "  Found multiple types%s%s\n",
	       function_entry_reached ? " (function entry reached)" : "",
	       function_entry_reached ? " (multiple types encountered)" : "");
    }

  return false;
}

/* See if speculation given by SPEC_OUTER_TYPE, SPEC_OFFSET and SPEC_MAYBE_DERIVED_TYPE
   seems consistent (and useful) with what we already have in the non-speculative context.  */

bool
ipa_polymorphic_call_context::speculation_consistent_p (tree spec_outer_type,
							HOST_WIDE_INT spec_offset,
							bool spec_maybe_derived_type,
							tree otr_type) const
{
  if (!flag_devirtualize_speculatively)
    return false;

  /* Non-polymorphic types are useless for deriving likely polymorphic
     call targets.  */
  if (!spec_outer_type || !contains_polymorphic_type_p (spec_outer_type))
    return false;

  /* If we know nothing, speculation is always good.  */
  if (!outer_type)
    return true;

  /* Speculation is only useful to avoid derived types.
     This is not 100% true for placement new, where the outer context may
     turn out to be useless, but ignore these for now.  */
  if (!maybe_derived_type)
    return false;

  /* If types agrees, speculation is consistent, but it makes sense only
     when it says something new.  */
  if (types_must_be_same_for_odr (spec_outer_type, outer_type))
    return maybe_derived_type && !spec_maybe_derived_type;

  /* If speculation does not contain the type in question, ignore it.  */
  if (otr_type
      && !contains_type_p (spec_outer_type, spec_offset, otr_type, false, true))
    return false;

  /* If outer type already contains speculation as a filed,
     it is useless.  We already know from OUTER_TYPE 
     SPEC_TYPE and that it is not in the construction.  */
  if (contains_type_p (outer_type, offset - spec_offset,
		       spec_outer_type, false, false))
    return false;

  /* If speculative outer type is not more specified than outer
     type, just give up. 
     We can only decide this safely if we can compare types with OUTER_TYPE.
   */
  if ((!in_lto_p || odr_type_p (outer_type))
      && !contains_type_p (spec_outer_type,
			   spec_offset - offset,
			   outer_type, false))
    return false;
  return true;
}

/* Improve THIS with speculation described by NEW_OUTER_TYPE, NEW_OFFSET,
   NEW_MAYBE_DERIVED_TYPE 
   If OTR_TYPE is set, assume the context is used with OTR_TYPE.  */

bool
ipa_polymorphic_call_context::combine_speculation_with
   (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
    tree otr_type)
{
  if (!new_outer_type)
    return false;

  /* restrict_to_inner_class may eliminate wrong speculation making our job
     easeier.  */
  if (otr_type)
    restrict_to_inner_class (otr_type);

  if (!speculation_consistent_p (new_outer_type, new_offset,
				 new_maybe_derived_type, otr_type))
    return false;

  /* New speculation is a win in case we have no speculation or new
     speculation does not consider derivations.  */
  if (!speculative_outer_type
      || (speculative_maybe_derived_type
	  && !new_maybe_derived_type))
    {
      speculative_outer_type = new_outer_type;
      speculative_offset = new_offset;
      speculative_maybe_derived_type = new_maybe_derived_type;
      return true;
    }
  else if (types_must_be_same_for_odr (speculative_outer_type,
				       new_outer_type))
    {
      if (speculative_offset != new_offset)
	{
	  /* OK we have two contexts that seems valid but they disagree,
	     just give up.

	     This is not a lattice operation, so we may want to drop it later.  */
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file,
		     "Speculative outer types match, "
		     "offset mismatch -> invalid speculation\n");
	  clear_speculation ();
	  return true;
	}
      else
	{
	  if (speculative_maybe_derived_type && !new_maybe_derived_type)
	    {
	      speculative_maybe_derived_type = false;
	      return true;
	    }
	  else
	    return false;
	}
    }
  /* Choose type that contains the other.  This one either contains the outer
     as a field (thus giving exactly one target) or is deeper in the type
     hiearchy.  */
  else if (speculative_outer_type
	   && speculative_maybe_derived_type
	   && (new_offset > speculative_offset
	       || (new_offset == speculative_offset
		   && contains_type_p (new_outer_type,
				       0, speculative_outer_type, false))))
    {
      tree old_outer_type = speculative_outer_type;
      HOST_WIDE_INT old_offset = speculative_offset;
      bool old_maybe_derived_type = speculative_maybe_derived_type;

      speculative_outer_type = new_outer_type;
      speculative_offset = new_offset;
      speculative_maybe_derived_type = new_maybe_derived_type;

      if (otr_type)
	restrict_to_inner_class (otr_type);

      /* If the speculation turned out to make no sense, revert to sensible
	 one.  */
      if (!speculative_outer_type)
	{
	  speculative_outer_type = old_outer_type;
	  speculative_offset = old_offset;
	  speculative_maybe_derived_type = old_maybe_derived_type;
	  return false;
	}
      return (old_offset != speculative_offset
	      || old_maybe_derived_type != speculative_maybe_derived_type
	      || types_must_be_same_for_odr (speculative_outer_type,
					     new_outer_type));
    }
  return false;
}

/* Make speculation less specific so
   NEW_OUTER_TYPE, NEW_OFFSET, NEW_MAYBE_DERIVED_TYPE is also included.
   If OTR_TYPE is set, assume the context is used with OTR_TYPE.  */

bool
ipa_polymorphic_call_context::meet_speculation_with
   (tree new_outer_type, HOST_WIDE_INT new_offset, bool new_maybe_derived_type,
    tree otr_type)
{
  if (!new_outer_type && speculative_outer_type)
    {
      clear_speculation ();
      return true;
    }

  /* restrict_to_inner_class may eliminate wrong speculation making our job
     easeier.  */
  if (otr_type)
    restrict_to_inner_class (otr_type);

  if (!speculative_outer_type
      || !speculation_consistent_p (speculative_outer_type,
				    speculative_offset,
				    speculative_maybe_derived_type,
				    otr_type))
    return false;

  if (!speculation_consistent_p (new_outer_type, new_offset,
				 new_maybe_derived_type, otr_type))
    {
      clear_speculation ();
      return true;
    }

  else if (types_must_be_same_for_odr (speculative_outer_type,
				       new_outer_type))
    {
      if (speculative_offset != new_offset)
	{
	  clear_speculation ();
	  return true;
	}
      else
	{
	  if (!speculative_maybe_derived_type && new_maybe_derived_type)
	    {
	      speculative_maybe_derived_type = true;
	      return true;
	    }
	  else
	    return false;
	}
    }
  /* See if one type contains the other as a field (not base).  */
  else if (contains_type_p (new_outer_type, new_offset - speculative_offset,
			    speculative_outer_type, false, false))
    return false;
  else if (contains_type_p (speculative_outer_type,
			    speculative_offset - new_offset,
			    new_outer_type, false, false))
    {
      speculative_outer_type = new_outer_type;
      speculative_offset = new_offset;
      speculative_maybe_derived_type = new_maybe_derived_type;
      return true;
    }
  /* See if OUTER_TYPE is base of CTX.OUTER_TYPE.  */
  else if (contains_type_p (new_outer_type,
			    new_offset - speculative_offset,
			    speculative_outer_type, false, true))
    {
      if (!speculative_maybe_derived_type)
	{
	  speculative_maybe_derived_type = true;
	  return true;
	}
      return false;
    }
  /* See if CTX.OUTER_TYPE is base of OUTER_TYPE.  */
  else if (contains_type_p (speculative_outer_type,
			    speculative_offset - new_offset, new_outer_type, false, true))
    {
      speculative_outer_type = new_outer_type;
      speculative_offset = new_offset;
      speculative_maybe_derived_type = true;
      return true;
    }
  else
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "Giving up on speculative meet\n");
      clear_speculation ();
      return true;
    }
}

/* Assume that both THIS and a given context is valid and strenghten THIS
   if possible.  Return true if any strenghtening was made.
   If actual type the context is being used in is known, OTR_TYPE should be
   set accordingly. This improves quality of combined result.  */

bool
ipa_polymorphic_call_context::combine_with (ipa_polymorphic_call_context ctx,
					    tree otr_type)
{
  bool updated = false;

  if (ctx.useless_p () || invalid)
    return false;

  /* Restricting context to inner type makes merging easier, however do not
     do that unless we know how the context is used (OTR_TYPE is non-NULL)  */
  if (otr_type && !invalid && !ctx.invalid)
    {
      restrict_to_inner_class (otr_type);
      ctx.restrict_to_inner_class (otr_type);
      if(invalid)
        return false;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Polymorphic call context combine:");
      dump (dump_file);
      fprintf (dump_file, "With context:                    ");
      ctx.dump (dump_file);
      if (otr_type)
	{
          fprintf (dump_file, "To be used with type:            ");
	  print_generic_expr (dump_file, otr_type, TDF_SLIM);
          fprintf (dump_file, "\n");
	}
    }

  /* If call is known to be invalid, we are done.  */
  if (ctx.invalid)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "-> Invalid context\n");
      goto invalidate;
    }

  if (!ctx.outer_type)
    ;
  else if (!outer_type)
    {
      outer_type = ctx.outer_type;
      offset = ctx.offset;
      dynamic = ctx.dynamic;
      maybe_in_construction = ctx.maybe_in_construction;
      maybe_derived_type = ctx.maybe_derived_type;
      updated = true;
    }
  /* If types are known to be same, merging is quite easy.  */
  else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
    {
      if (offset != ctx.offset
	  && TYPE_SIZE (outer_type)
	  && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Outer types match, offset mismatch -> invalid\n");
	  clear_speculation ();
	  clear_outer_type ();
	  invalid = true;
	  return true;
	}
      if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "Outer types match, merging flags\n");
      if (maybe_in_construction && !ctx.maybe_in_construction)
	{
	  updated = true;
	  maybe_in_construction = false;
	}
      if (maybe_derived_type && !ctx.maybe_derived_type)
	{
	  updated = true;
	  maybe_derived_type = false;
	}
      if (dynamic && !ctx.dynamic)
	{
	  updated = true;
	  dynamic = false;
	}
    }
  /* If we know the type precisely, there is not much to improve.  */
  else if (!maybe_derived_type && !maybe_in_construction
	   && !ctx.maybe_derived_type && !ctx.maybe_in_construction)
    {
      /* It may be easy to check if second context permits the first
	 and set INVALID otherwise.  This is not easy to do in general;
	 contains_type_p may return false negatives for non-comparable
	 types.  

	 If OTR_TYPE is known, we however can expect that
	 restrict_to_inner_class should have discovered the same base
	 type.  */
      if (otr_type && !ctx.maybe_in_construction && !ctx.maybe_derived_type)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Contextes disagree -> invalid\n");
	  goto invalidate;
	}
    }
  /* See if one type contains the other as a field (not base).
     In this case we want to choose the wider type, because it contains
     more information.  */
  else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
			    outer_type, false, false))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Second type contain the first as a field\n");

      if (maybe_derived_type)
	{
	  outer_type = ctx.outer_type;
	  maybe_derived_type = ctx.maybe_derived_type;
	  offset = ctx.offset;
	  dynamic = ctx.dynamic;
	  updated = true;
	}

      /* If we do not know how the context is being used, we can
	 not clear MAYBE_IN_CONSTRUCTION because it may be offseted
	 to other component of OUTER_TYPE later and we know nothing
	 about it.  */
      if (otr_type && maybe_in_construction
	  && !ctx.maybe_in_construction)
	{
          maybe_in_construction = false;
	  updated = true;
	}
    }
  else if (contains_type_p (outer_type, offset - ctx.offset,
			    ctx.outer_type, false, false))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "First type contain the second as a field\n");

      if (otr_type && maybe_in_construction
	  && !ctx.maybe_in_construction)
	{
          maybe_in_construction = false;
	  updated = true;
	}
    }
  /* See if OUTER_TYPE is base of CTX.OUTER_TYPE.  */
  else if (contains_type_p (ctx.outer_type,
			    ctx.offset - offset, outer_type, false, true))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "First type is base of second\n");
      if (!maybe_derived_type)
	{
	  if (!ctx.maybe_in_construction
	      && types_odr_comparable (outer_type, ctx.outer_type))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "Second context does not permit base -> invalid\n");
	      goto invalidate;
	    }
	}
      /* Pick variant deeper in the hiearchy.  */
      else
	{
	  outer_type = ctx.outer_type;
	  maybe_in_construction = ctx.maybe_in_construction;
	  maybe_derived_type = ctx.maybe_derived_type;
	  offset = ctx.offset;
	  dynamic = ctx.dynamic;
          updated = true;
	}
    }
  /* See if CTX.OUTER_TYPE is base of OUTER_TYPE.  */
  else if (contains_type_p (outer_type,
			    offset - ctx.offset, ctx.outer_type, false, true))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Second type is base of first\n");
      if (!ctx.maybe_derived_type)
	{
	  if (!maybe_in_construction
	      && types_odr_comparable (outer_type, ctx.outer_type))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "First context does not permit base -> invalid\n");
	      goto invalidate;
	    }
	  /* Pick the base type.  */
	  else if (maybe_in_construction)
	    {
	      outer_type = ctx.outer_type;
	      maybe_in_construction = ctx.maybe_in_construction;
	      maybe_derived_type = ctx.maybe_derived_type;
	      offset = ctx.offset;
	      dynamic = ctx.dynamic;
	      updated = true;
	    }
	}
    }
  /* TODO handle merging using hiearchy. */
  else if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Giving up on merge\n");

  updated |= combine_speculation_with (ctx.speculative_outer_type,
				       ctx.speculative_offset,
				       ctx.speculative_maybe_derived_type,
				       otr_type);

  if (updated && dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Updated as:                      ");
      dump (dump_file);
      fprintf (dump_file, "\n");
    }
  return updated;

invalidate:
  invalid = true;
  clear_speculation ();
  clear_outer_type ();
  return true;
}

/* Take non-speculative info, merge it with speculative and clear speculation.
   Used when we no longer manage to keep track of actual outer type, but we
   think it is still there.

   If OTR_TYPE is set, the transformation can be done more effectively assuming
   that context is going to be used only that way.  */

void
ipa_polymorphic_call_context::make_speculative (tree otr_type)
{
  tree spec_outer_type = outer_type;
  HOST_WIDE_INT spec_offset = offset;
  bool spec_maybe_derived_type = maybe_derived_type;

  if (invalid)
    {
      invalid = false;
      clear_outer_type ();
      clear_speculation ();
      return;
    }
  if (!outer_type)
    return;
  clear_outer_type ();
  combine_speculation_with (spec_outer_type, spec_offset,
			    spec_maybe_derived_type,
			    otr_type);
}

/* Use when we can not track dynamic type change.  This speculatively assume
   type change is not happening.  */

void
ipa_polymorphic_call_context::possible_dynamic_type_change (bool in_poly_cdtor,
							    tree otr_type)
{
  if (dynamic)
    make_speculative (otr_type);
  else if (in_poly_cdtor)
    maybe_in_construction = true;
}

/* Return TRUE if this context conveys the same information as OTHER.  */

bool
ipa_polymorphic_call_context::equal_to
    (const ipa_polymorphic_call_context &x) const
{
  if (useless_p ())
    return x.useless_p ();
  if (invalid)
    return x.invalid;
  if (x.useless_p () || x.invalid)
    return false;

  if (outer_type)
    {
      if (!x.outer_type
	  || !types_odr_comparable (outer_type, x.outer_type)
	  || !types_same_for_odr (outer_type, x.outer_type)
	  || offset != x.offset
	  || maybe_in_construction != x.maybe_in_construction
	  || maybe_derived_type != x.maybe_derived_type
	  || dynamic != x.dynamic)
	return false;
    }
  else if (x.outer_type)
    return false;


  if (speculative_outer_type
      && speculation_consistent_p (speculative_outer_type, speculative_offset,
				   speculative_maybe_derived_type, NULL_TREE))
    {
      if (!x.speculative_outer_type)
	return false;

      if (!types_odr_comparable (speculative_outer_type,
				 x.speculative_outer_type)
	  || !types_same_for_odr  (speculative_outer_type,
				   x.speculative_outer_type)
	  || speculative_offset != x.speculative_offset
	  || speculative_maybe_derived_type != x.speculative_maybe_derived_type)
	return false;
    }
  else if (x.speculative_outer_type
	   && x.speculation_consistent_p (x.speculative_outer_type,
					  x.speculative_offset,
				  	  x.speculative_maybe_derived_type,
					  NULL))
    return false;

  return true;
}

/* Modify context to be strictly less restrictive than CTX.  */

bool
ipa_polymorphic_call_context::meet_with (ipa_polymorphic_call_context ctx,
					 tree otr_type)
{
  bool updated = false;

  if (useless_p () || ctx.invalid)
    return false;

  /* Restricting context to inner type makes merging easier, however do not
     do that unless we know how the context is used (OTR_TYPE is non-NULL)  */
  if (otr_type && !useless_p () && !ctx.useless_p ())
    {
      restrict_to_inner_class (otr_type);
      ctx.restrict_to_inner_class (otr_type);
      if(invalid)
        return false;
    }

  if (equal_to (ctx))
    return false;

  if (ctx.useless_p () || invalid)
    {
      *this = ctx;
      return true;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Polymorphic call context meet:");
      dump (dump_file);
      fprintf (dump_file, "With context:                    ");
      ctx.dump (dump_file);
      if (otr_type)
	{
          fprintf (dump_file, "To be used with type:            ");
	  print_generic_expr (dump_file, otr_type, TDF_SLIM);
          fprintf (dump_file, "\n");
	}
    }

  if (!dynamic && ctx.dynamic)
    {
      dynamic = true;
      updated = true;
    }

  /* If call is known to be invalid, we are done.  */
  if (!outer_type)
    ;
  else if (!ctx.outer_type)
    {
      clear_outer_type ();
      updated = true;
    }
  /* If types are known to be same, merging is quite easy.  */
  else if (types_must_be_same_for_odr (outer_type, ctx.outer_type))
    {
      if (offset != ctx.offset
	  && TYPE_SIZE (outer_type)
	  && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Outer types match, offset mismatch -> clearing\n");
	  clear_outer_type ();
	  return true;
	}
      if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "Outer types match, merging flags\n");
      if (!maybe_in_construction && ctx.maybe_in_construction)
	{
	  updated = true;
	  maybe_in_construction = true;
	}
      if (!maybe_derived_type && ctx.maybe_derived_type)
	{
	  updated = true;
	  maybe_derived_type = true;
	}
      if (!dynamic && ctx.dynamic)
	{
	  updated = true;
	  dynamic = true;
	}
    }
  /* See if one type contains the other as a field (not base).  */
  else if (contains_type_p (ctx.outer_type, ctx.offset - offset,
			    outer_type, false, false))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Second type contain the first as a field\n");

      /* The second type is more specified, so we keep the first.
         We need to set DYNAMIC flag to avoid declaring context INVALID
	 of OFFSET ends up being out of range.  */
      if (!dynamic
	  && (ctx.dynamic
	      || (!otr_type
		  && (!TYPE_SIZE (ctx.outer_type)
		      || !TYPE_SIZE (outer_type)
		      || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
					   TYPE_SIZE (outer_type), 0)))))
	{
	  dynamic = true;
	  updated = true;
	}
    }
  else if (contains_type_p (outer_type, offset - ctx.offset,
			    ctx.outer_type, false, false))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "First type contain the second as a field\n");

      if (!dynamic
	  && (ctx.dynamic
	      || (!otr_type
		  && (!TYPE_SIZE (ctx.outer_type)
		      || !TYPE_SIZE (outer_type)
		      || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
					   TYPE_SIZE (outer_type), 0)))))
	dynamic = true;
      outer_type = ctx.outer_type;
      offset = ctx.offset;
      dynamic = ctx.dynamic;
      maybe_in_construction = ctx.maybe_in_construction;
      maybe_derived_type = ctx.maybe_derived_type;
      updated = true;
    }
  /* See if OUTER_TYPE is base of CTX.OUTER_TYPE.  */
  else if (contains_type_p (ctx.outer_type,
			    ctx.offset - offset, outer_type, false, true))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "First type is base of second\n");
      if (!maybe_derived_type)
	{
	  maybe_derived_type = true;
	  updated = true;
	}
      if (!maybe_in_construction && ctx.maybe_in_construction)
	{
	  maybe_in_construction = true;
	  updated = true;
	}
      if (!dynamic && ctx.dynamic)
	{
	  dynamic = true;
	  updated = true;
	}
    }
  /* See if CTX.OUTER_TYPE is base of OUTER_TYPE.  */
  else if (contains_type_p (outer_type,
			    offset - ctx.offset, ctx.outer_type, false, true))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Second type is base of first\n");
      outer_type = ctx.outer_type;
      offset = ctx.offset;
      updated = true;
      if (!maybe_derived_type)
	maybe_derived_type = true;
      if (!maybe_in_construction && ctx.maybe_in_construction)
	maybe_in_construction = true;
      if (!dynamic && ctx.dynamic)
	dynamic = true;
    }
  /* TODO handle merging using hiearchy. */
  else
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "Giving up on meet\n");
      clear_outer_type ();
      updated = true;
    }

  updated |= meet_speculation_with (ctx.speculative_outer_type,
				    ctx.speculative_offset,
				    ctx.speculative_maybe_derived_type,
				    otr_type);

  if (updated && dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Updated as:                      ");
      dump (dump_file);
      fprintf (dump_file, "\n");
    }
  return updated;
}
