/* Search for references that a functions loads or stores.
   Copyright (C) 2020-2022 Free Software Foundation, Inc.
   Contributed by David Cepelik and 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/>.  */

/* Mod/ref pass records summary about loads and stores performed by the
   function.  This is later used by alias analysis to disambiguate memory
   accesses across function calls.

   This file contains a tree pass and an IPA pass.  Both performs the same
   analysis however tree pass is executed during early and late optimization
   passes to propagate info downwards in the compilation order.  IPA pass
   propagates across the callgraph and is able to handle recursion and works on
   whole program during link-time analysis.

   LTO mode differs from the local mode by not recording alias sets but types
   that are translated to alias sets later.  This is necessary in order stream
   the information because the alias sets are rebuild at stream-in time and may
   not correspond to ones seen during analysis.  For this reason part of
   analysis is duplicated.

   The following information is computed
     1) load/store access tree described in ipa-modref-tree.h
	This is used by tree-ssa-alias to disambiguate load/stores
     2) EAF flags used by points-to analysis (in tree-ssa-structlias).
	and defined in tree-core.h.
   and stored to optimization_summaries.

   There are multiple summaries computed and used during the propagation:
     - summaries holds summaries from analysis to IPA propagation
       time.
     - summaries_lto is same as summaries but holds them in a format
       that can be streamed (as described above).
     - fnspec_summary holds fnspec strings for call.  This is
       necessary because gimple_call_fnspec performs additional
       analysis except for looking callee fndecl.
     - escape_summary holds escape points for given call edge.
       That is a vector recording what function parmaeters
       may escape to a function call (and with what parameter index).  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "gimple-iterator.h"
#include "tree-dfa.h"
#include "cgraph.h"
#include "ipa-utils.h"
#include "symbol-summary.h"
#include "gimple-pretty-print.h"
#include "gimple-walk.h"
#include "print-tree.h"
#include "tree-streamer.h"
#include "alias.h"
#include "calls.h"
#include "ipa-modref-tree.h"
#include "ipa-modref.h"
#include "value-range.h"
#include "ipa-prop.h"
#include "ipa-fnsummary.h"
#include "attr-fnspec.h"
#include "symtab-clones.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "tree-ssa-operands.h"
#include "ssa-iterators.h"
#include "stringpool.h"
#include "tree-ssanames.h"
#include "attribs.h"
#include "tree-cfg.h"
#include "tree-eh.h"


namespace {

/* We record fnspec specifiers for call edges since they depends on actual
   gimple statements.  */

class fnspec_summary
{
public:
  char *fnspec;

  fnspec_summary ()
  : fnspec (NULL)
  {
  }

  ~fnspec_summary ()
  {
    free (fnspec);
  }
};

/* Summary holding fnspec string for a given call.  */

class fnspec_summaries_t : public call_summary <fnspec_summary *>
{
public:
  fnspec_summaries_t (symbol_table *symtab)
      : call_summary <fnspec_summary *> (symtab) {}
  /* Hook that is called by summary when an edge is duplicated.  */
  virtual void duplicate (cgraph_edge *,
			  cgraph_edge *,
			  fnspec_summary *src,
			  fnspec_summary *dst)
  {
    dst->fnspec = xstrdup (src->fnspec);
  }
};

static fnspec_summaries_t *fnspec_summaries = NULL;

/* Escape summary holds a vector of param indexes that escape to
   a given call.  */
struct escape_entry
{
  /* Parameter that escapes at a given call.  */
  int parm_index;
  /* Argument it escapes to.  */
  unsigned int arg;
  /* Minimal flags known about the argument.  */
  eaf_flags_t min_flags;
  /* Does it escape directly or indirectly?  */
  bool direct;
};

/* Dump EAF flags.  */

static void
dump_eaf_flags (FILE *out, int flags, bool newline = true)
{
  if (flags & EAF_UNUSED)
    fprintf (out, " unused");
  if (flags & EAF_NO_DIRECT_CLOBBER)
    fprintf (out, " no_direct_clobber");
  if (flags & EAF_NO_INDIRECT_CLOBBER)
    fprintf (out, " no_indirect_clobber");
  if (flags & EAF_NO_DIRECT_ESCAPE)
    fprintf (out, " no_direct_escape");
  if (flags & EAF_NO_INDIRECT_ESCAPE)
    fprintf (out, " no_indirect_escape");
  if (flags & EAF_NOT_RETURNED_DIRECTLY)
    fprintf (out, " not_returned_directly");
  if (flags & EAF_NOT_RETURNED_INDIRECTLY)
    fprintf (out, " not_returned_indirectly");
  if (flags & EAF_NO_DIRECT_READ)
    fprintf (out, " no_direct_read");
  if (flags & EAF_NO_INDIRECT_READ)
    fprintf (out, " no_indirect_read");
  if (newline)
  fprintf (out, "\n");
}

struct escape_summary
{
  auto_vec <escape_entry> esc;
  void dump (FILE *out)
  {
    for (unsigned int i = 0; i < esc.length (); i++)
      {
	fprintf (out, "   parm %i arg %i %s min:",
		 esc[i].parm_index,
		 esc[i].arg,
		 esc[i].direct ? "(direct)" : "(indirect)");
	dump_eaf_flags (out, esc[i].min_flags, false);
      }
    fprintf (out, "\n");
  }
};

class escape_summaries_t : public call_summary <escape_summary *>
{
public:
  escape_summaries_t (symbol_table *symtab)
      : call_summary <escape_summary *> (symtab) {}
  /* Hook that is called by summary when an edge is duplicated.  */
  virtual void duplicate (cgraph_edge *,
			  cgraph_edge *,
			  escape_summary *src,
			  escape_summary *dst)
  {
    dst->esc = src->esc.copy ();
  }
};

static escape_summaries_t *escape_summaries = NULL;

}  /* ANON namespace: GTY annotated summaries can not be anonymous.  */


/* Class (from which there is one global instance) that holds modref summaries
   for all analyzed functions.  */

class GTY((user)) modref_summaries
  : public fast_function_summary <modref_summary *, va_gc>
{
public:
  modref_summaries (symbol_table *symtab)
      : fast_function_summary <modref_summary *, va_gc> (symtab) {}
  virtual void insert (cgraph_node *, modref_summary *state);
  virtual void duplicate (cgraph_node *src_node,
			  cgraph_node *dst_node,
			  modref_summary *src_data,
			  modref_summary *dst_data);
  static modref_summaries *create_ggc (symbol_table *symtab)
  {
    return new (ggc_alloc_no_dtor<modref_summaries> ())
	     modref_summaries (symtab);
  }
};

class modref_summary_lto;

/* Class (from which there is one global instance) that holds modref summaries
   for all analyzed functions.  */

class GTY((user)) modref_summaries_lto
  : public fast_function_summary <modref_summary_lto *, va_gc>
{
public:
  modref_summaries_lto (symbol_table *symtab)
      : fast_function_summary <modref_summary_lto *, va_gc> (symtab),
	propagated (false) {}
  virtual void insert (cgraph_node *, modref_summary_lto *state);
  virtual void duplicate (cgraph_node *src_node,
			  cgraph_node *dst_node,
			  modref_summary_lto *src_data,
			  modref_summary_lto *dst_data);
  static modref_summaries_lto *create_ggc (symbol_table *symtab)
  {
    return new (ggc_alloc_no_dtor<modref_summaries_lto> ())
	     modref_summaries_lto (symtab);
  }
  bool propagated;
};

/* Global variable holding all modref summaries
   (from analysis to IPA propagation time).  */

static GTY(()) fast_function_summary <modref_summary *, va_gc>
	 *summaries;

/* Global variable holding all modref optimization summaries
   (from IPA propagation time or used by local optimization pass).  */

static GTY(()) fast_function_summary <modref_summary *, va_gc>
	 *optimization_summaries;

/* LTO summaries hold info from analysis to LTO streaming or from LTO
   stream-in through propagation to LTO stream-out.  */

static GTY(()) fast_function_summary <modref_summary_lto *, va_gc>
	 *summaries_lto;

/* Summary for a single function which this pass produces.  */

modref_summary::modref_summary ()
  : loads (NULL), stores (NULL), retslot_flags (0), static_chain_flags (0),
    writes_errno (false), side_effects (false), nondeterministic (false),
    calls_interposable (false), global_memory_read (false),
    global_memory_written (false), try_dse (false)
{
}

modref_summary::~modref_summary ()
{
  if (loads)
    ggc_delete (loads);
  if (stores)
    ggc_delete (stores);
}

/* Remove all flags from EAF_FLAGS that are implied by ECF_FLAGS and not
   useful to track.  If returns_void is true moreover clear
   EAF_NOT_RETURNED.  */
static int
remove_useless_eaf_flags (int eaf_flags, int ecf_flags, bool returns_void)
{
  if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
    eaf_flags &= ~implicit_const_eaf_flags;
  else if (ecf_flags & ECF_PURE)
    eaf_flags &= ~implicit_pure_eaf_flags;
  else if ((ecf_flags & ECF_NORETURN) || returns_void)
    eaf_flags &= ~(EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY);
  return eaf_flags;
}

/* Return true if FLAGS holds some useful information.  */

static bool
eaf_flags_useful_p (vec <eaf_flags_t> &flags, int ecf_flags)
{
  for (unsigned i = 0; i < flags.length (); i++)
    if (remove_useless_eaf_flags (flags[i], ecf_flags, false))
      return true;
  return false;
}

/* Return true if summary is potentially useful for optimization.
   If CHECK_FLAGS is false assume that arg_flags are useful.  */

bool
modref_summary::useful_p (int ecf_flags, bool check_flags)
{
  if (arg_flags.length () && !check_flags)
    return true;
  if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags))
    return true;
  arg_flags.release ();
  if (check_flags && remove_useless_eaf_flags (retslot_flags, ecf_flags, false))
    return true;
  if (check_flags
      && remove_useless_eaf_flags (static_chain_flags, ecf_flags, false))
    return true;
  if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
    return ((!side_effects || !nondeterministic)
	    && (ecf_flags & ECF_LOOPING_CONST_OR_PURE));
  if (loads && !loads->every_base)
    return true;
  else
    kills.release ();
  if (ecf_flags & ECF_PURE)
    return ((!side_effects || !nondeterministic)
	    && (ecf_flags & ECF_LOOPING_CONST_OR_PURE));
  return stores && !stores->every_base;
}

/* Single function summary used for LTO.  */

typedef modref_tree <tree> modref_records_lto;
struct GTY(()) modref_summary_lto
{
  /* Load and stores in functions using types rather then alias sets.

     This is necessary to make the information streamable for LTO but is also
     more verbose and thus more likely to hit the limits.  */
  modref_records_lto *loads;
  modref_records_lto *stores;
  auto_vec<modref_access_node> GTY((skip)) kills;
  auto_vec<eaf_flags_t> GTY((skip)) arg_flags;
  eaf_flags_t retslot_flags;
  eaf_flags_t static_chain_flags;
  unsigned writes_errno : 1;
  unsigned side_effects : 1;
  unsigned nondeterministic : 1;
  unsigned calls_interposable : 1;

  modref_summary_lto ();
  ~modref_summary_lto ();
  void dump (FILE *);
  bool useful_p (int ecf_flags, bool check_flags = true);
};

/* Summary for a single function which this pass produces.  */

modref_summary_lto::modref_summary_lto ()
  : loads (NULL), stores (NULL), retslot_flags (0), static_chain_flags (0),
    writes_errno (false), side_effects (false), nondeterministic (false),
    calls_interposable (false)
{
}

modref_summary_lto::~modref_summary_lto ()
{
  if (loads)
    ggc_delete (loads);
  if (stores)
    ggc_delete (stores);
}


/* Return true if lto summary is potentially useful for optimization.
   If CHECK_FLAGS is false assume that arg_flags are useful.  */

bool
modref_summary_lto::useful_p (int ecf_flags, bool check_flags)
{
  if (arg_flags.length () && !check_flags)
    return true;
  if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags))
    return true;
  arg_flags.release ();
  if (check_flags && remove_useless_eaf_flags (retslot_flags, ecf_flags, false))
    return true;
  if (check_flags
      && remove_useless_eaf_flags (static_chain_flags, ecf_flags, false))
    return true;
  if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
    return ((!side_effects || !nondeterministic)
	    && (ecf_flags & ECF_LOOPING_CONST_OR_PURE));
  if (loads && !loads->every_base)
    return true;
  else
    kills.release ();
  if (ecf_flags & ECF_PURE)
    return ((!side_effects || !nondeterministic)
	    && (ecf_flags & ECF_LOOPING_CONST_OR_PURE));
  return stores && !stores->every_base;
}

/* Dump records TT to OUT.  */

static void
dump_records (modref_records *tt, FILE *out)
{
  if (tt->every_base)
    {
      fprintf (out, "    Every base\n");
      return;
    }
  size_t i;
  modref_base_node <alias_set_type> *n;
  FOR_EACH_VEC_SAFE_ELT (tt->bases, i, n)
    {
      fprintf (out, "      Base %i: alias set %i\n", (int)i, n->base);
      if (n->every_ref)
	{
	  fprintf (out, "      Every ref\n");
	  continue;
	}
      size_t j;
      modref_ref_node <alias_set_type> *r;
      FOR_EACH_VEC_SAFE_ELT (n->refs, j, r)
	{
	  fprintf (out, "        Ref %i: alias set %i\n", (int)j, r->ref);
	  if (r->every_access)
	    {
	      fprintf (out, "          Every access\n");
	      continue;
	    }
	  size_t k;
	  modref_access_node *a;
	  FOR_EACH_VEC_SAFE_ELT (r->accesses, k, a)
	    {
	      fprintf (out, "          access:");
	      a->dump (out);
	    }
	}
    }
}

/* Dump records TT to OUT.  */

static void
dump_lto_records (modref_records_lto *tt, FILE *out)
{
  if (tt->every_base)
    {
      fprintf (out, "    Every base\n");
      return;
    }
  size_t i;
  modref_base_node <tree> *n;
  FOR_EACH_VEC_SAFE_ELT (tt->bases, i, n)
    {
      fprintf (out, "      Base %i:", (int)i);
      print_generic_expr (dump_file, n->base);
      fprintf (out, " (alias set %i)\n",
	       n->base ? get_alias_set (n->base) : 0);
      if (n->every_ref)
	{
	  fprintf (out, "      Every ref\n");
	  continue;
	}
      size_t j;
      modref_ref_node <tree> *r;
      FOR_EACH_VEC_SAFE_ELT (n->refs, j, r)
	{
	  fprintf (out, "        Ref %i:", (int)j);
	  print_generic_expr (dump_file, r->ref);
	  fprintf (out, " (alias set %i)\n",
		   r->ref ? get_alias_set (r->ref) : 0);
	  if (r->every_access)
	    {
	      fprintf (out, "          Every access\n");
	      continue;
	    }
	  size_t k;
	  modref_access_node *a;
	  FOR_EACH_VEC_SAFE_ELT (r->accesses, k, a)
	    {
	      fprintf (out, "          access:");
	      a->dump (out);
	    }
	}
    }
}

/* Dump all escape points of NODE to OUT.  */

static void
dump_modref_edge_summaries (FILE *out, cgraph_node *node, int depth)
{
  int i = 0;
  if (!escape_summaries)
    return;
  for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee)
    {
      class escape_summary *sum = escape_summaries->get (e);
      if (sum)
	{
	  fprintf (out, "%*sIndirect call %i in %s escapes:",
		   depth, "", i, node->dump_name ());
	  sum->dump (out);
	}
      i++;
    }
  for (cgraph_edge *e = node->callees; e; e = e->next_callee)
    {
      if (!e->inline_failed)
	dump_modref_edge_summaries (out, e->callee, depth + 1);
      class escape_summary *sum = escape_summaries->get (e);
      if (sum)
	{
	  fprintf (out, "%*sCall %s->%s escapes:", depth, "",
		   node->dump_name (), e->callee->dump_name ());
	  sum->dump (out);
	}
      class fnspec_summary *fsum = fnspec_summaries->get (e);
      if (fsum)
	{
	  fprintf (out, "%*sCall %s->%s fnspec: %s\n", depth, "",
		   node->dump_name (), e->callee->dump_name (),
		   fsum->fnspec);
	}
    }
}

/* Remove all call edge summaries associated with NODE.  */

static void
remove_modref_edge_summaries (cgraph_node *node)
{
  if (!escape_summaries)
    return;
  for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee)
    escape_summaries->remove (e);
  for (cgraph_edge *e = node->callees; e; e = e->next_callee)
    {
      if (!e->inline_failed)
	remove_modref_edge_summaries (e->callee);
      escape_summaries->remove (e);
      fnspec_summaries->remove (e);
    }
}

/* Dump summary.  */

void
modref_summary::dump (FILE *out)
{
  if (loads)
    {
      fprintf (out, "  loads:\n");
      dump_records (loads, out);
    }
  if (stores)
    {
      fprintf (out, "  stores:\n");
      dump_records (stores, out);
    }
  if (kills.length ())
    {
      fprintf (out, "  kills:\n");
      for (auto kill : kills)
	{
	  fprintf (out, "    ");
	  kill.dump (out);
	}
    }
  if (writes_errno)
    fprintf (out, "  Writes errno\n");
  if (side_effects)
    fprintf (out, "  Side effects\n");
  if (nondeterministic)
    fprintf (out, "  Nondeterministic\n");
  if (calls_interposable)
    fprintf (out, "  Calls interposable\n");
  if (global_memory_read)
    fprintf (out, "  Global memory read\n");
  if (global_memory_written)
    fprintf (out, "  Global memory written\n");
  if (try_dse)
    fprintf (out, "  Try dse\n");
  if (arg_flags.length ())
    {
      for (unsigned int i = 0; i < arg_flags.length (); i++)
	if (arg_flags[i])
	  {
	    fprintf (out, "  parm %i flags:", i);
	    dump_eaf_flags (out, arg_flags[i]);
	  }
    }
  if (retslot_flags)
    {
      fprintf (out, "  Retslot flags:");
      dump_eaf_flags (out, retslot_flags);
    }
  if (static_chain_flags)
    {
      fprintf (out, "  Static chain flags:");
      dump_eaf_flags (out, static_chain_flags);
    }
}

/* Dump summary.  */

void
modref_summary_lto::dump (FILE *out)
{
  fprintf (out, "  loads:\n");
  dump_lto_records (loads, out);
  fprintf (out, "  stores:\n");
  dump_lto_records (stores, out);
  if (kills.length ())
    {
      fprintf (out, "  kills:\n");
      for (auto kill : kills)
	{
	  fprintf (out, "    ");
	  kill.dump (out);
	}
    }
  if (writes_errno)
    fprintf (out, "  Writes errno\n");
  if (side_effects)
    fprintf (out, "  Side effects\n");
  if (nondeterministic)
    fprintf (out, "  Nondeterministic\n");
  if (calls_interposable)
    fprintf (out, "  Calls interposable\n");
  if (arg_flags.length ())
    {
      for (unsigned int i = 0; i < arg_flags.length (); i++)
	if (arg_flags[i])
	  {
	    fprintf (out, "  parm %i flags:", i);
	    dump_eaf_flags (out, arg_flags[i]);
	  }
    }
  if (retslot_flags)
    {
      fprintf (out, "  Retslot flags:");
      dump_eaf_flags (out, retslot_flags);
    }
  if (static_chain_flags)
    {
      fprintf (out, "  Static chain flags:");
      dump_eaf_flags (out, static_chain_flags);
    }
}

/* Called after summary is produced and before it is used by local analysis.
   Can be called multiple times in case summary needs to update signature.
   FUN is decl of function summary is attached to.  */
void
modref_summary::finalize (tree fun)
{
  global_memory_read = !loads || loads->global_access_p ();
  global_memory_written = !stores || stores->global_access_p ();

  /* We can do DSE if we know function has no side effects and
     we can analyse all stores.  Disable dse if there are too many
     stores to try.  */
  if (side_effects || global_memory_written || writes_errno)
    try_dse = false;
  else
    {
      try_dse = true;
      size_t i, j, k;
      int num_tests = 0, max_tests
	= opt_for_fn (fun, param_modref_max_tests);
      modref_base_node <alias_set_type> *base_node;
      modref_ref_node <alias_set_type> *ref_node;
      modref_access_node *access_node;
      FOR_EACH_VEC_SAFE_ELT (stores->bases, i, base_node)
	{
	  if (base_node->every_ref)
	    {
	      try_dse = false;
	      break;
	    }
	  FOR_EACH_VEC_SAFE_ELT (base_node->refs, j, ref_node)
	    {
	      if (base_node->every_ref)
		{
		  try_dse = false;
		  break;
		}
	      FOR_EACH_VEC_SAFE_ELT (ref_node->accesses, k, access_node)
		if (num_tests++ > max_tests
		    || !access_node->parm_offset_known)
		  {
		    try_dse = false;
		    break;
		  }
	      if (!try_dse)
		break;
	    }
	  if (!try_dse)
	    break;
	}
    }
  if (loads->every_base)
    load_accesses = 1;
  else
    {
      load_accesses = 0;
      for (auto base_node : loads->bases)
	{
	  if (base_node->every_ref)
	    load_accesses++;
	  else
	    for (auto ref_node : base_node->refs)
	      if (ref_node->every_access)
		load_accesses++;
	      else
		load_accesses += ref_node->accesses->length ();
	}
    }
}

/* Get function summary for FUNC if it exists, return NULL otherwise.  */

modref_summary *
get_modref_function_summary (cgraph_node *func)
{
  /* Avoid creation of the summary too early (e.g. when front-end calls us).  */
  if (!optimization_summaries)
    return NULL;

  /* A single function body may be represented by multiple symbols with
     different visibility.  For example, if FUNC is an interposable alias,
     we don't want to return anything, even if we have summary for the target
     function.  */
  enum availability avail;
  func = func->ultimate_alias_target
		 (&avail, current_function_decl ?
			  cgraph_node::get (current_function_decl) : NULL);
  if (avail <= AVAIL_INTERPOSABLE)
    return NULL;

  modref_summary *r = optimization_summaries->get (func);
  return r;
}

/* Get function summary for CALL if it exists, return NULL otherwise.
   If non-null set interposed to indicate whether function may not
   bind to current def.  In this case sometimes loads from function
   needs to be ignored.  */

modref_summary *
get_modref_function_summary (gcall *call, bool *interposed)
{
  tree callee = gimple_call_fndecl (call);
  if (!callee)
    return NULL;
  struct cgraph_node *node = cgraph_node::get (callee);
  if (!node)
    return NULL;
  modref_summary *r = get_modref_function_summary (node);
  if (interposed && r)
    *interposed = r->calls_interposable
		  || !node->binds_to_current_def_p ();
  return r;
}


namespace {

/* Return true if ECF flags says that nondeterminsm can be ignored.  */

static bool
ignore_nondeterminism_p (tree caller, int flags)
{
  if (flags & (ECF_CONST | ECF_PURE))
    return true;
  if ((flags & (ECF_NORETURN | ECF_NOTHROW)) == (ECF_NORETURN | ECF_NOTHROW)
      || (!opt_for_fn (caller, flag_exceptions) && (flags & ECF_NORETURN)))
    return true;
  return false;
}

/* Return true if ECF flags says that return value can be ignored.  */

static bool
ignore_retval_p (tree caller, int flags)
{
  if ((flags & (ECF_NORETURN | ECF_NOTHROW)) == (ECF_NORETURN | ECF_NOTHROW)
      || (!opt_for_fn (caller, flag_exceptions) && (flags & ECF_NORETURN)))
    return true;
  return false;
}

/* Return true if ECF flags says that stores can be ignored.  */

static bool
ignore_stores_p (tree caller, int flags)
{
  if (flags & (ECF_PURE | ECF_CONST | ECF_NOVOPS))
    return true;
  if ((flags & (ECF_NORETURN | ECF_NOTHROW)) == (ECF_NORETURN | ECF_NOTHROW)
      || (!opt_for_fn (caller, flag_exceptions) && (flags & ECF_NORETURN)))
    return true;
  return false;
}

/* Determine parm_map for PTR which is supposed to be a pointer.  */

modref_parm_map
parm_map_for_ptr (tree op)
{
  bool offset_known;
  poly_int64 offset;
  struct modref_parm_map parm_map;
  gcall *call;

  parm_map.parm_offset_known = false;
  parm_map.parm_offset = 0;

  offset_known = unadjusted_ptr_and_unit_offset (op, &op, &offset);
  if (TREE_CODE (op) == SSA_NAME
      && SSA_NAME_IS_DEFAULT_DEF (op)
      && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
    {
      int index = 0;

      if (cfun->static_chain_decl
	  && op == ssa_default_def (cfun, cfun->static_chain_decl))
	index = MODREF_STATIC_CHAIN_PARM;
      else
	for (tree t = DECL_ARGUMENTS (current_function_decl);
	     t != SSA_NAME_VAR (op); t = DECL_CHAIN (t))
	  index++;
      parm_map.parm_index = index;
      parm_map.parm_offset_known = offset_known;
      parm_map.parm_offset = offset;
    }
  else if (points_to_local_or_readonly_memory_p (op))
    parm_map.parm_index = MODREF_LOCAL_MEMORY_PARM;
  /* Memory allocated in the function is not visible to caller before the
     call and thus we do not need to record it as load/stores/kills.  */
  else if (TREE_CODE (op) == SSA_NAME
	   && (call = dyn_cast<gcall *>(SSA_NAME_DEF_STMT (op))) != NULL
	   && gimple_call_flags (call) & ECF_MALLOC)
    parm_map.parm_index = MODREF_LOCAL_MEMORY_PARM;
  else
    parm_map.parm_index = MODREF_UNKNOWN_PARM;
  return parm_map;
}

/* Return true if ARG with EAF flags FLAGS can not make any caller's parameter
   used (if LOAD is true we check loads, otherwise stores).  */

static bool
verify_arg (tree arg, int flags, bool load)
{
  if (flags & EAF_UNUSED)
    return true;
  if (load && (flags & EAF_NO_DIRECT_READ))
    return true;
  if (!load
      && (flags & (EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER))
	  == (EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER))
    return true;
  if (is_gimple_constant (arg))
    return true;
  if (DECL_P (arg) && TREE_READONLY (arg))
    return true;
  if (TREE_CODE (arg) == ADDR_EXPR)
    {
      tree t = get_base_address (TREE_OPERAND (arg, 0));
      if (is_gimple_constant (t))
	return true;
      if (DECL_P (t)
	  && (TREE_READONLY (t) || TREE_CODE (t) == FUNCTION_DECL))
	return true;
    }
  return false;
}

/* Return true if STMT may access memory that is pointed to by parameters
   of caller and which is not seen as an escape by PTA.
   CALLEE_ECF_FLAGS are ECF flags of callee.  If LOAD is true then by access
   we mean load, otherwise we mean store.  */

static bool
may_access_nonescaping_parm_p (gcall *call, int callee_ecf_flags, bool load)
{
  int implicit_flags = 0;

  if (ignore_stores_p (current_function_decl, callee_ecf_flags))
    implicit_flags |= ignore_stores_eaf_flags;
  if (callee_ecf_flags & ECF_PURE)
    implicit_flags |= implicit_pure_eaf_flags;
  if (callee_ecf_flags & (ECF_CONST | ECF_NOVOPS))
    implicit_flags |= implicit_const_eaf_flags;
  if (gimple_call_chain (call)
      && !verify_arg (gimple_call_chain (call),
		      gimple_call_static_chain_flags (call) | implicit_flags,
		      load))
    return true;
  for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
    if (!verify_arg (gimple_call_arg (call, i),
		     gimple_call_arg_flags (call, i) | implicit_flags,
		     load))
      return true;
  return false;
}


/* Analyze memory accesses (loads, stores and kills) performed
   by the function.  Set also side_effects, calls_interposable
   and nondeterminism flags.  */

class modref_access_analysis
{
public:
  modref_access_analysis (bool ipa, modref_summary *summary,
			  modref_summary_lto *summary_lto)
  : m_summary (summary), m_summary_lto (summary_lto), m_ipa (ipa)
  {
  }
  void analyze ();
private:
  bool set_side_effects ();
  bool set_nondeterministic ();
  static modref_access_node get_access (ao_ref *ref);
  static void record_access (modref_records *, ao_ref *, modref_access_node &);
  static void record_access_lto (modref_records_lto *, ao_ref *,
				 modref_access_node &a);
  bool record_access_p (tree);
  bool record_unknown_load ();
  bool record_unknown_store ();
  bool record_global_memory_load ();
  bool record_global_memory_store ();
  bool merge_call_side_effects (gimple *, modref_summary *,
				cgraph_node *, bool);
  modref_access_node get_access_for_fnspec (gcall *, attr_fnspec &,
					    unsigned int, modref_parm_map &);
  void process_fnspec (gcall *);
  void analyze_call (gcall *);
  static bool analyze_load (gimple *, tree, tree, void *);
  static bool analyze_store (gimple *, tree, tree, void *);
  void analyze_stmt (gimple *, bool);
  void propagate ();

  /* Summary being computed.
     We work eitehr with m_summary or m_summary_lto.  Never on both.  */
  modref_summary *m_summary;
  modref_summary_lto *m_summary_lto;
  /* Recursive calls needs simplisitc dataflow after analysis finished.
     Collect all calls into this vector during analysis and later process
     them in propagate.  */
  auto_vec <gimple *, 32> m_recursive_calls;
  /* ECF flags of function being analysed.  */
  int m_ecf_flags;
  /* True if IPA propagation will be done later.  */
  bool m_ipa;
  /* Set true if statement currently analysed is known to be
     executed each time function is called.  */
  bool m_always_executed;
};

/* Set side_effects flag and return if someting changed.  */

bool
modref_access_analysis::set_side_effects ()
{
  bool changed = false;

  if (m_summary && !m_summary->side_effects)
    {
      m_summary->side_effects = true;
      changed = true;
    }
  if (m_summary_lto && !m_summary_lto->side_effects)
    {
      m_summary_lto->side_effects = true;
      changed = true;
    }
  return changed;
}

/* Set nondeterministic flag and return if someting changed.  */

bool
modref_access_analysis::set_nondeterministic ()
{
  bool changed = false;

  if (m_summary && !m_summary->nondeterministic)
    {
      m_summary->side_effects = m_summary->nondeterministic = true;
      changed = true;
    }
  if (m_summary_lto && !m_summary_lto->nondeterministic)
    {
      m_summary_lto->side_effects = m_summary_lto->nondeterministic = true;
      changed = true;
    }
  return changed;
}

/* Construct modref_access_node from REF.  */

modref_access_node
modref_access_analysis::get_access (ao_ref *ref)
{
  tree base;

  base = ao_ref_base (ref);
  modref_access_node a = {ref->offset, ref->size, ref->max_size,
			  0, MODREF_UNKNOWN_PARM, false, 0};
  if (TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF)
    {
      tree memref = base;
      modref_parm_map m = parm_map_for_ptr (TREE_OPERAND (base, 0));

      a.parm_index = m.parm_index;
      if (a.parm_index != MODREF_UNKNOWN_PARM && TREE_CODE (memref) == MEM_REF)
	{
	  a.parm_offset_known
	     = wi::to_poly_wide (TREE_OPERAND
				     (memref, 1)).to_shwi (&a.parm_offset);
	  if (a.parm_offset_known && m.parm_offset_known)
	    a.parm_offset += m.parm_offset;
	  else
	    a.parm_offset_known = false;
	}
    }
  else
    a.parm_index = MODREF_UNKNOWN_PARM;
  return a;
}

/* Record access into the modref_records data structure.  */

void
modref_access_analysis::record_access (modref_records *tt,
				       ao_ref *ref,
				       modref_access_node &a)
{
  alias_set_type base_set = !flag_strict_aliasing
			    || !flag_ipa_strict_aliasing ? 0
			    : ao_ref_base_alias_set (ref);
  alias_set_type ref_set = !flag_strict_aliasing
			   || !flag_ipa_strict_aliasing ? 0
			    : (ao_ref_alias_set (ref));
  if (dump_file)
    {
       fprintf (dump_file, "   - Recording base_set=%i ref_set=%i ",
		base_set, ref_set);
       a.dump (dump_file);
    }
  tt->insert (current_function_decl, base_set, ref_set, a, false);
}

/* IPA version of record_access_tree.  */

void
modref_access_analysis::record_access_lto (modref_records_lto *tt, ao_ref *ref,
					   modref_access_node &a)
{
  /* get_alias_set sometimes use different type to compute the alias set
     than TREE_TYPE (base).  Do same adjustments.  */
  tree base_type = NULL_TREE, ref_type = NULL_TREE;
  if (flag_strict_aliasing && flag_ipa_strict_aliasing)
    {
      tree base;

      base = ref->ref;
      while (handled_component_p (base))
	base = TREE_OPERAND (base, 0);

      base_type = reference_alias_ptr_type_1 (&base);

      if (!base_type)
	base_type = TREE_TYPE (base);
      else
	base_type = TYPE_REF_CAN_ALIAS_ALL (base_type)
		    ? NULL_TREE : TREE_TYPE (base_type);

      tree ref_expr = ref->ref;
      ref_type = reference_alias_ptr_type_1 (&ref_expr);

      if (!ref_type)
	ref_type = TREE_TYPE (ref_expr);
      else
	ref_type = TYPE_REF_CAN_ALIAS_ALL (ref_type)
		   ? NULL_TREE : TREE_TYPE (ref_type);

      /* Sanity check that we are in sync with what get_alias_set does.  */
      gcc_checking_assert ((!base_type && !ao_ref_base_alias_set (ref))
			   || get_alias_set (base_type)
			      == ao_ref_base_alias_set (ref));
      gcc_checking_assert ((!ref_type && !ao_ref_alias_set (ref))
			   || get_alias_set (ref_type)
			      == ao_ref_alias_set (ref));

      /* Do not bother to record types that have no meaningful alias set.
	 Also skip variably modified types since these go to local streams.  */
      if (base_type && (!get_alias_set (base_type)
			|| variably_modified_type_p (base_type, NULL_TREE)))
	base_type = NULL_TREE;
      if (ref_type && (!get_alias_set (ref_type)
		       || variably_modified_type_p (ref_type, NULL_TREE)))
	ref_type = NULL_TREE;
    }
  if (dump_file)
    {
      fprintf (dump_file, "   - Recording base type:");
      print_generic_expr (dump_file, base_type);
      fprintf (dump_file, " (alias set %i) ref type:",
	       base_type ? get_alias_set (base_type) : 0);
      print_generic_expr (dump_file, ref_type);
      fprintf (dump_file, " (alias set %i) ",
	       ref_type ? get_alias_set (ref_type) : 0);
       a.dump (dump_file);
    }

  tt->insert (current_function_decl, base_type, ref_type, a, false);
}

/* Returns true if and only if we should store the access to EXPR.
   Some accesses, e.g. loads from automatic variables, are not interesting.  */

bool
modref_access_analysis::record_access_p (tree expr)
{
  if (TREE_THIS_VOLATILE (expr))
    {
      if (dump_file)
	fprintf (dump_file, " (volatile; marking nondeterministic) ");
      set_nondeterministic ();
    }
  if (cfun->can_throw_non_call_exceptions
      && tree_could_throw_p (expr))
    {
      if (dump_file)
	fprintf (dump_file, " (can throw; marking side effects) ");
      set_side_effects ();
    }

  if (refs_local_or_readonly_memory_p (expr))
    {
      if (dump_file)
	fprintf (dump_file, "   - Read-only or local, ignoring.\n");
      return false;
    }
  return true;
}

/* Collapse loads and return true if something changed.  */

bool
modref_access_analysis::record_unknown_load ()
{
  bool changed = false;

  if (m_summary && !m_summary->loads->every_base)
    {
      m_summary->loads->collapse ();
      changed = true;
    }
  if (m_summary_lto && !m_summary_lto->loads->every_base)
    {
      m_summary_lto->loads->collapse ();
      changed = true;
    }
  return changed;
}

/* Collapse loads and return true if something changed.  */

bool
modref_access_analysis::record_unknown_store ()
{
  bool changed = false;

  if (m_summary && !m_summary->stores->every_base)
    {
      m_summary->stores->collapse ();
      changed = true;
    }
  if (m_summary_lto && !m_summary_lto->stores->every_base)
    {
      m_summary_lto->stores->collapse ();
      changed = true;
    }
  return changed;
}

/* Record unknown load from gloal memory.  */

bool
modref_access_analysis::record_global_memory_load ()
{
  bool changed = false;
  modref_access_node a = {0, -1, -1,
			  0, MODREF_GLOBAL_MEMORY_PARM, false, 0};

  if (m_summary && !m_summary->loads->every_base)
    changed |= m_summary->loads->insert (current_function_decl, 0, 0, a, false);
  if (m_summary_lto && !m_summary_lto->loads->every_base)
    changed |= m_summary_lto->loads->insert (current_function_decl,
					     0, 0, a, false);
  return changed;
}

/* Record unknown store from gloal memory.  */

bool
modref_access_analysis::record_global_memory_store ()
{
  bool changed = false;
  modref_access_node a = {0, -1, -1,
			  0, MODREF_GLOBAL_MEMORY_PARM, false, 0};

  if (m_summary && !m_summary->stores->every_base)
    changed |= m_summary->stores->insert (current_function_decl,
					  0, 0, a, false);
  if (m_summary_lto && !m_summary_lto->stores->every_base)
    changed |= m_summary_lto->stores->insert (current_function_decl,
					     0, 0, a, false);
  return changed;
}

/* Merge side effects of call STMT to function with CALLEE_SUMMARY.
   Return true if something changed.
   If IGNORE_STORES is true, do not merge stores.
   If RECORD_ADJUSTMENTS is true cap number of adjustments to
   a given access to make dataflow finite.  */

bool
modref_access_analysis::merge_call_side_effects
	 (gimple *stmt, modref_summary *callee_summary,
	  cgraph_node *callee_node, bool record_adjustments)
{
  gcall *call = as_a <gcall *> (stmt);
  int flags = gimple_call_flags (call);

  /* Nothing to do for non-looping cont functions.  */
  if ((flags & (ECF_CONST | ECF_NOVOPS))
      && !(flags & ECF_LOOPING_CONST_OR_PURE))
    return false;

  bool changed = false;

  if (dump_file)
    fprintf (dump_file, " - Merging side effects of %s\n",
	     callee_node->dump_name ());

  /* Merge side effects and non-determinism.
     PURE/CONST flags makes functions deterministic and if there is
     no LOOPING_CONST_OR_PURE they also have no side effects.  */
  if (!(flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE))
      || (flags & ECF_LOOPING_CONST_OR_PURE))
    {
      if (!m_summary->side_effects && callee_summary->side_effects)
	{
	  if (dump_file)
	    fprintf (dump_file, " - merging side effects.\n");
	  m_summary->side_effects = true;
	  changed = true;
	}
      if (!m_summary->nondeterministic && callee_summary->nondeterministic
	  && !ignore_nondeterminism_p (current_function_decl, flags))
	{
	  if (dump_file)
	    fprintf (dump_file, " - merging nondeterministic.\n");
	  m_summary->nondeterministic = true;
	  changed = true;
	}
     }

  /* For const functions we are done.  */
  if (flags & (ECF_CONST | ECF_NOVOPS))
    return changed;

  /* Merge calls_interposable flags.  */
  if (!m_summary->calls_interposable && callee_summary->calls_interposable)
    {
      if (dump_file)
	fprintf (dump_file, " - merging calls interposable.\n");
      m_summary->calls_interposable = true;
      changed = true;
    }

  if (!callee_node->binds_to_current_def_p () && !m_summary->calls_interposable)
    {
      if (dump_file)
	fprintf (dump_file, " - May be interposed.\n");
      m_summary->calls_interposable = true;
      changed = true;
    }

  /* Now merge the actual load, store and kill vectors.  For this we need
     to compute map translating new parameters to old.  */
  if (dump_file)
    fprintf (dump_file, "   Parm map:");

  auto_vec <modref_parm_map, 32> parm_map;
  parm_map.safe_grow_cleared (gimple_call_num_args (call), true);
  for (unsigned i = 0; i < gimple_call_num_args (call); i++)
    {
      parm_map[i] = parm_map_for_ptr (gimple_call_arg (call, i));
      if (dump_file)
	{
	  fprintf (dump_file, " %i", parm_map[i].parm_index);
	  if (parm_map[i].parm_offset_known)
	    {
	      fprintf (dump_file, " offset:");
	      print_dec ((poly_int64_pod)parm_map[i].parm_offset,
			 dump_file, SIGNED);
	    }
	}
    }

  modref_parm_map chain_map;
  if (gimple_call_chain (call))
    {
      chain_map = parm_map_for_ptr (gimple_call_chain (call));
      if (dump_file)
	{
	  fprintf (dump_file, "static chain %i", chain_map.parm_index);
	  if (chain_map.parm_offset_known)
	    {
	      fprintf (dump_file, " offset:");
	      print_dec ((poly_int64_pod)chain_map.parm_offset,
			 dump_file, SIGNED);
	    }
	}
    }
  if (dump_file)
    fprintf (dump_file, "\n");

  /* Kills can me merged in only if we know the function is going to be
     always executed.  */
  if (m_always_executed
      && callee_summary->kills.length ()
      && (!cfun->can_throw_non_call_exceptions
	  || !stmt_could_throw_p (cfun, call)))
    {
      /* Watch for self recursive updates.  */
      auto_vec<modref_access_node, 32> saved_kills;

      saved_kills.reserve_exact (callee_summary->kills.length ());
      saved_kills.splice (callee_summary->kills);
      for (auto kill : saved_kills)
	{
	  if (kill.parm_index >= (int)parm_map.length ())
	    continue;
	  modref_parm_map &m
		  = kill.parm_index == MODREF_STATIC_CHAIN_PARM
		    ? chain_map
		    : parm_map[kill.parm_index];
	  if (m.parm_index == MODREF_LOCAL_MEMORY_PARM
	      || m.parm_index == MODREF_UNKNOWN_PARM
	      || m.parm_index == MODREF_RETSLOT_PARM
	      || !m.parm_offset_known)
	    continue;
	  modref_access_node n = kill;
	  n.parm_index = m.parm_index;
	  n.parm_offset += m.parm_offset;
	  if (modref_access_node::insert_kill (m_summary->kills, n,
					       record_adjustments))
	    changed = true;
	}
    }

  /* Merge in loads.  */
  changed |= m_summary->loads->merge (current_function_decl,
				      callee_summary->loads,
				      &parm_map, &chain_map,
				      record_adjustments,
				      !may_access_nonescaping_parm_p
					 (call, flags, true));
  /* Merge in stores.  */
  if (!ignore_stores_p (current_function_decl, flags))
    {
      changed |= m_summary->stores->merge (current_function_decl,
					   callee_summary->stores,
					   &parm_map, &chain_map,
					   record_adjustments,
					   !may_access_nonescaping_parm_p
					       (call, flags, false));
      if (!m_summary->writes_errno
	  && callee_summary->writes_errno)
	{
	  m_summary->writes_errno = true;
	  changed = true;
	}
    }
  return changed;
}

/* Return access mode for argument I of call STMT with FNSPEC.  */

modref_access_node
modref_access_analysis::get_access_for_fnspec (gcall *call, attr_fnspec &fnspec,
					       unsigned int i,
					       modref_parm_map &map)
{
  tree size = NULL_TREE;
  unsigned int size_arg;

  if (!fnspec.arg_specified_p (i))
    ;
  else if (fnspec.arg_max_access_size_given_by_arg_p (i, &size_arg))
    size = gimple_call_arg (call, size_arg);
  else if (fnspec.arg_access_size_given_by_type_p (i))
    {
      tree callee = gimple_call_fndecl (call);
      tree t = TYPE_ARG_TYPES (TREE_TYPE (callee));

      for (unsigned int p = 0; p < i; p++)
	t = TREE_CHAIN (t);
      size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_VALUE (t)));
    }
  modref_access_node a = {0, -1, -1,
			  map.parm_offset, map.parm_index,
			  map.parm_offset_known, 0};
  poly_int64 size_hwi;
  if (size
      && poly_int_tree_p (size, &size_hwi)
      && coeffs_in_range_p (size_hwi, 0,
			    HOST_WIDE_INT_MAX / BITS_PER_UNIT))
    {
      a.size = -1;
      a.max_size = size_hwi << LOG2_BITS_PER_UNIT;
    }
  return a;
}
/* Apply side effects of call STMT to CUR_SUMMARY using FNSPEC.
   If IGNORE_STORES is true ignore them.
   Return false if no useful summary can be produced.   */

void
modref_access_analysis::process_fnspec (gcall *call)
{
  int flags = gimple_call_flags (call);

  /* PURE/CONST flags makes functions deterministic and if there is
     no LOOPING_CONST_OR_PURE they also have no side effects.  */
  if (!(flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE))
      || (flags & ECF_LOOPING_CONST_OR_PURE)
      || (cfun->can_throw_non_call_exceptions
	  && stmt_could_throw_p (cfun, call)))
    {
      set_side_effects ();
      if (!ignore_nondeterminism_p (current_function_decl, flags))
	set_nondeterministic ();
    }

  /* For const functions we are done.  */
  if (flags & (ECF_CONST | ECF_NOVOPS))
    return;

  attr_fnspec fnspec = gimple_call_fnspec (call);
  /* If there is no fnpec we know nothing about loads & stores.  */
  if (!fnspec.known_p ())
    {
      if (dump_file && gimple_call_builtin_p (call, BUILT_IN_NORMAL))
	fprintf (dump_file, "      Builtin with no fnspec: %s\n",
		 IDENTIFIER_POINTER (DECL_NAME (gimple_call_fndecl (call))));
      if (!ignore_stores_p (current_function_decl, flags))
	{
	  if (!may_access_nonescaping_parm_p (call, flags, false))
	    record_global_memory_store ();
	  else
	    record_unknown_store ();
	  if (!may_access_nonescaping_parm_p (call, flags, true))
	    record_global_memory_load ();
	  else
	    record_unknown_load ();
	}
      else
	{
	  if (!may_access_nonescaping_parm_p (call, flags, true))
	    record_global_memory_load ();
	  else
	    record_unknown_load ();
	}
      return;
    }
  /* Process fnspec.  */
  if (fnspec.global_memory_read_p ())
    {
      if (may_access_nonescaping_parm_p (call, flags, true))
	record_unknown_load ();
      else
	record_global_memory_load ();
    }
  else
    {
      for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
	if (!POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, i))))
	  ;
	else if (!fnspec.arg_specified_p (i)
		 || fnspec.arg_maybe_read_p (i))
	  {
	    modref_parm_map map = parm_map_for_ptr
					(gimple_call_arg (call, i));

	    if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
	      continue;
	    if (map.parm_index == MODREF_UNKNOWN_PARM)
	      {
		record_unknown_load ();
		break;
	      }
	    modref_access_node a = get_access_for_fnspec (call, fnspec, i, map);
	    if (a.parm_index == MODREF_LOCAL_MEMORY_PARM)
	      continue;
	    if (m_summary)
	      m_summary->loads->insert (current_function_decl, 0, 0, a, false);
	    if (m_summary_lto)
	      m_summary_lto->loads->insert (current_function_decl, 0, 0, a,
					    false);
	  }
    }
  if (ignore_stores_p (current_function_decl, flags))
    return;
  if (fnspec.global_memory_written_p ())
    {
      if (may_access_nonescaping_parm_p (call, flags, false))
	record_unknown_store ();
      else
	record_global_memory_store ();
    }
  else
    {
      for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
	if (!POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, i))))
	  ;
	else if (!fnspec.arg_specified_p (i)
		 || fnspec.arg_maybe_written_p (i))
	  {
	    modref_parm_map map = parm_map_for_ptr
					 (gimple_call_arg (call, i));

	    if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
	      continue;
	    if (map.parm_index == MODREF_UNKNOWN_PARM)
	      {
		record_unknown_store ();
		break;
	      }
	    modref_access_node a = get_access_for_fnspec (call, fnspec, i, map);
	    if (a.parm_index == MODREF_LOCAL_MEMORY_PARM)
	      continue;
	    if (m_summary)
	      m_summary->stores->insert (current_function_decl, 0, 0, a, false);
	    if (m_summary_lto)
	      m_summary_lto->stores->insert (current_function_decl,
					     0, 0, a, false);
	  }
      if (fnspec.errno_maybe_written_p () && flag_errno_math)
	{
	  if (m_summary)
	    m_summary->writes_errno = true;
	  if (m_summary_lto)
	    m_summary_lto->writes_errno = true;
	}
    }
}

/* Analyze function call STMT in function F.
   Remember recursive calls in RECURSIVE_CALLS.  */

void
modref_access_analysis::analyze_call (gcall *stmt)
{
  /* Check flags on the function call.  In certain cases, analysis can be
     simplified.  */
  int flags = gimple_call_flags (stmt);

  if (dump_file)
    {
      fprintf (dump_file, " - Analyzing call:");
      print_gimple_stmt (dump_file, stmt, 0);
    }

  if ((flags & (ECF_CONST | ECF_NOVOPS))
      && !(flags & ECF_LOOPING_CONST_OR_PURE))
    {
      if (dump_file)
	fprintf (dump_file,
		 " - ECF_CONST | ECF_NOVOPS, ignoring all stores and all loads "
		 "except for args.\n");
      return;
    }

  /* Next, we try to get the callee's function declaration.  The goal is to
     merge their summary with ours.  */
  tree callee = gimple_call_fndecl (stmt);

  /* Check if this is an indirect call.  */
  if (!callee)
    {
      if (dump_file)
	fprintf (dump_file, gimple_call_internal_p (stmt)
		 ? " - Internal call" : " - Indirect call.\n");
      process_fnspec (stmt);
      return;
    }
  /* We only need to handle internal calls in IPA mode.  */
  gcc_checking_assert (!m_summary_lto && !m_ipa);

  struct cgraph_node *callee_node = cgraph_node::get_create (callee);

  /* If this is a recursive call, the target summary is the same as ours, so
     there's nothing to do.  */
  if (recursive_call_p (current_function_decl, callee))
    {
      m_recursive_calls.safe_push (stmt);
      set_side_effects ();
      if (dump_file)
	fprintf (dump_file, " - Skipping recursive call.\n");
      return;
    }

  gcc_assert (callee_node != NULL);

  /* Get the function symbol and its availability.  */
  enum availability avail;
  callee_node = callee_node->function_symbol (&avail);
  bool looping;
  if (builtin_safe_for_const_function_p (&looping, callee))
    {
      if (looping)
	set_side_effects ();
      if (dump_file)
	fprintf (dump_file, " - Builtin is safe for const.\n");
      return;
    }
  if (avail <= AVAIL_INTERPOSABLE)
    {
      if (dump_file)
	fprintf (dump_file,
		 " - Function availability <= AVAIL_INTERPOSABLE.\n");
      process_fnspec (stmt);
      return;
    }

  /* Get callee's modref summary.  As above, if there's no summary, we either
     have to give up or, if stores are ignored, we can just purge loads.  */
  modref_summary *callee_summary = optimization_summaries->get (callee_node);
  if (!callee_summary)
    {
      if (dump_file)
	fprintf (dump_file, " - No modref summary available for callee.\n");
      process_fnspec (stmt);
      return;
    }

  merge_call_side_effects (stmt, callee_summary, callee_node, false);

  return;
}

/* Helper for analyze_stmt.  */

bool
modref_access_analysis::analyze_load (gimple *, tree, tree op, void *data)
{
  modref_access_analysis *t = (modref_access_analysis *)data;

  if (dump_file)
    {
      fprintf (dump_file, " - Analyzing load: ");
      print_generic_expr (dump_file, op);
      fprintf (dump_file, "\n");
    }

  if (!t->record_access_p (op))
    return false;

  ao_ref r;
  ao_ref_init (&r, op);
  modref_access_node a = get_access (&r);
  if (a.parm_index == MODREF_LOCAL_MEMORY_PARM)
    return false;

  if (t->m_summary)
    t->record_access (t->m_summary->loads, &r, a);
  if (t->m_summary_lto)
    t->record_access_lto (t->m_summary_lto->loads, &r, a);
  return false;
}

/* Helper for analyze_stmt.  */

bool
modref_access_analysis::analyze_store (gimple *stmt, tree, tree op, void *data)
{
  modref_access_analysis *t = (modref_access_analysis *)data;

  if (dump_file)
    {
      fprintf (dump_file, " - Analyzing store: ");
      print_generic_expr (dump_file, op);
      fprintf (dump_file, "\n");
    }

  if (!t->record_access_p (op))
    return false;

  ao_ref r;
  ao_ref_init (&r, op);
  modref_access_node a = get_access (&r);
  if (a.parm_index == MODREF_LOCAL_MEMORY_PARM)
    return false;

  if (t->m_summary)
    t->record_access (t->m_summary->stores, &r, a);
  if (t->m_summary_lto)
    t->record_access_lto (t->m_summary_lto->stores, &r, a);
  if (t->m_always_executed
      && a.useful_for_kill_p ()
      && (!cfun->can_throw_non_call_exceptions
	  || !stmt_could_throw_p (cfun, stmt)))
    {
      if (dump_file)
	fprintf (dump_file, "   - Recording kill\n");
      if (t->m_summary)
	modref_access_node::insert_kill (t->m_summary->kills, a, false);
      if (t->m_summary_lto)
	modref_access_node::insert_kill (t->m_summary_lto->kills, a, false);
    }
  return false;
}

/* Analyze statement STMT of function F.
   If IPA is true do not merge in side effects of calls.  */

void
modref_access_analysis::analyze_stmt (gimple *stmt, bool always_executed)
{
  m_always_executed = always_executed;
  /* In general we can not ignore clobbers because they are barriers for code
     motion, however after inlining it is safe to do because local optimization
     passes do not consider clobbers from other functions.
     Similar logic is in ipa-pure-const.cc.  */
  if ((m_ipa || cfun->after_inlining) && gimple_clobber_p (stmt))
    {
      if (always_executed && record_access_p (gimple_assign_lhs (stmt)))
	{
	  ao_ref r;
	  ao_ref_init (&r, gimple_assign_lhs (stmt));
	  modref_access_node a = get_access (&r);
	  if (a.useful_for_kill_p ())
	    {
	      if (dump_file)
		fprintf (dump_file, "   - Recording kill\n");
	      if (m_summary)
		modref_access_node::insert_kill (m_summary->kills, a, false);
	      if (m_summary_lto)
		modref_access_node::insert_kill (m_summary_lto->kills,
						 a, false);
	    }
	}
      return;
    }

  /* Analyze all loads and stores in STMT.  */
  walk_stmt_load_store_ops (stmt, this,
			    analyze_load, analyze_store);

  switch (gimple_code (stmt))
   {
   case GIMPLE_ASM:
      if (gimple_asm_volatile_p (as_a <gasm *> (stmt)))
	set_nondeterministic ();
      if (cfun->can_throw_non_call_exceptions
	  && stmt_could_throw_p (cfun, stmt))
	set_side_effects ();
     /* If the ASM statement does not read nor write memory, there's nothing
	to do.  Otherwise just give up.  */
     if (!gimple_asm_clobbers_memory_p (as_a <gasm *> (stmt)))
       return;
     if (dump_file)
       fprintf (dump_file, " - Function contains GIMPLE_ASM statement "
	       "which clobbers memory.\n");
     record_unknown_load ();
     record_unknown_store ();
     return;
   case GIMPLE_CALL:
     if (!m_ipa || gimple_call_internal_p (stmt))
       analyze_call (as_a <gcall *> (stmt));
     else
       {
	 attr_fnspec fnspec = gimple_call_fnspec (as_a <gcall *>(stmt));

	 if (fnspec.known_p ()
	     && (!fnspec.global_memory_read_p ()
		 || !fnspec.global_memory_written_p ()))
	   {
	     cgraph_edge *e = cgraph_node::get
				  (current_function_decl)->get_edge (stmt);
	     if (e->callee)
	       {
		 fnspec_summaries->get_create (e)->fnspec
			  = xstrdup (fnspec.get_str ());
		 if (dump_file)
		   fprintf (dump_file, "  Recorded fnspec %s\n",
			    fnspec.get_str ());
	       }
	   }
       }
     return;
   default:
     if (cfun->can_throw_non_call_exceptions
	 && stmt_could_throw_p (cfun, stmt))
	set_side_effects ();
     return;
   }
}

/* Propagate load/stres acress recursive calls.  */

void
modref_access_analysis::propagate ()
{
  if (m_ipa && m_summary)
    return;

  bool changed = true;
  bool first = true;
  cgraph_node *fnode = cgraph_node::get (current_function_decl);

  m_always_executed = false;
  while (changed && m_summary->useful_p (m_ecf_flags, false))
    {
      changed = false;
      for (unsigned i = 0; i < m_recursive_calls.length (); i++)
	{
	  changed |= merge_call_side_effects (m_recursive_calls[i], m_summary,
					      fnode, !first);
	}
      first = false;
    }
}

/* Analyze function.  */

void
modref_access_analysis::analyze ()
{
  m_ecf_flags = flags_from_decl_or_type (current_function_decl);
  bool summary_useful = true;

  /* Analyze each statement in each basic block of the function.  If the
     statement cannot be analyzed (for any reason), the entire function cannot
     be analyzed by modref.  */
  basic_block bb;
  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple_stmt_iterator si;
      bool always_executed
	      = bb == single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->dest;

      for (si = gsi_start_nondebug_after_labels_bb (bb);
	   !gsi_end_p (si); gsi_next_nondebug (&si))
	{
	  /* NULL memory accesses terminates BB.  These accesses are known
	     to trip undefined behaviour.  gimple-ssa-isolate-paths turns them
	     to volatile accesses and adds builtin_trap call which would
	     confuse us otherwise.  */
	  if (infer_nonnull_range_by_dereference (gsi_stmt (si),
						  null_pointer_node))
	    {
	      if (dump_file)
		fprintf (dump_file, " - NULL memory access; terminating BB\n");
	      if (flag_non_call_exceptions)
		set_side_effects ();
	      break;
	    }
	  analyze_stmt (gsi_stmt (si), always_executed);

	  /* Avoid doing useles work.  */
	  if ((!m_summary || !m_summary->useful_p (m_ecf_flags, false))
	      && (!m_summary_lto
		  || !m_summary_lto->useful_p (m_ecf_flags, false)))
	    {
	      summary_useful = false;
	      break;
	    }
	  if (always_executed
	      && stmt_can_throw_external (cfun, gsi_stmt (si)))
	    always_executed = false;
	}
      if (!summary_useful)
	break;
    }
  /* In non-IPA mode we need to perform iterative datafow on recursive calls.
     This needs to be done after all other side effects are computed.  */
  if (summary_useful)
    {
      if (!m_ipa)
	propagate ();
      if (m_summary && !m_summary->side_effects && !finite_function_p ())
	m_summary->side_effects = true;
      if (m_summary_lto && !m_summary_lto->side_effects
	  && !finite_function_p ())
	m_summary_lto->side_effects = true;
    }
}

/* Return true if OP accesses memory pointed to by SSA_NAME.  */

bool
memory_access_to (tree op, tree ssa_name)
{
  tree base = get_base_address (op);
  if (!base)
    return false;
  if (TREE_CODE (base) != MEM_REF && TREE_CODE (base) != TARGET_MEM_REF)
    return false;
  return TREE_OPERAND (base, 0) == ssa_name;
}

/* Consider statement val = *arg.
   return EAF flags of ARG that can be determined from EAF flags of VAL
   (which are known to be FLAGS).  If IGNORE_STORES is true we can ignore
   all stores to VAL, i.e. when handling noreturn function.  */

static int
deref_flags (int flags, bool ignore_stores)
{
  /* Dereference is also a direct read but dereferenced value does not
     yield any other direct use.  */
  int ret = EAF_NO_DIRECT_CLOBBER | EAF_NO_DIRECT_ESCAPE
	    | EAF_NOT_RETURNED_DIRECTLY;
  /* If argument is unused just account for
     the read involved in dereference.  */
  if (flags & EAF_UNUSED)
    ret |= EAF_NO_INDIRECT_READ | EAF_NO_INDIRECT_CLOBBER
	   | EAF_NO_INDIRECT_ESCAPE;
  else
    {
      /* Direct or indirect accesses leads to indirect accesses.  */
      if (((flags & EAF_NO_DIRECT_CLOBBER)
	   && (flags & EAF_NO_INDIRECT_CLOBBER))
	  || ignore_stores)
	ret |= EAF_NO_INDIRECT_CLOBBER;
      if (((flags & EAF_NO_DIRECT_ESCAPE)
	   && (flags & EAF_NO_INDIRECT_ESCAPE))
	  || ignore_stores)
	ret |= EAF_NO_INDIRECT_ESCAPE;
      if ((flags & EAF_NO_DIRECT_READ)
	   && (flags & EAF_NO_INDIRECT_READ))
	ret |= EAF_NO_INDIRECT_READ;
      if ((flags & EAF_NOT_RETURNED_DIRECTLY)
	  && (flags & EAF_NOT_RETURNED_INDIRECTLY))
	ret |= EAF_NOT_RETURNED_INDIRECTLY;
    }
  return ret;
}


/* Description of an escape point: a call which affects flags of a given
   SSA name.  */

struct escape_point
{
  /* Value escapes to this call.  */
  gcall *call;
  /* Argument it escapes to.  */
  int arg;
  /* Flags already known about the argument (this can save us from recording
     esape points if local analysis did good job already).  */
  eaf_flags_t min_flags;
  /* Does value escape directly or indiretly?  */
  bool direct;
};

/* Lattice used during the eaf flags analsysis dataflow.  For a given SSA name
   we aim to compute its flags and escape points.  We also use the lattice
   to dynamically build dataflow graph to propagate on.  */

class modref_lattice
{
public:
  /* EAF flags of the SSA name.  */
  eaf_flags_t flags;
  /* Used during DFS walk to mark names where final value was determined
     without need for dataflow.  */
  bool known;
  /* Used during DFS walk to mark open vertices (for cycle detection).  */
  bool open;
  /* Set during DFS walk for names that needs dataflow propagation.  */
  bool do_dataflow;
  /* Used during the iterative dataflow.  */
  bool changed;

  /* When doing IPA analysis we can not merge in callee escape points;
     Only remember them and do the merging at IPA propagation time.  */
  vec <escape_point, va_heap, vl_ptr> escape_points;

  /* Representation of a graph for dataaflow.  This graph is built on-demand
     using modref_eaf_analysis::analyze_ssa and later solved by
     modref_eaf_analysis::propagate.
     Each edge represents the fact that flags of current lattice should be
     propagated to lattice of SSA_NAME.  */
  struct propagate_edge
  {
    int ssa_name;
    bool deref;
  };
  vec <propagate_edge, va_heap, vl_ptr> propagate_to;

  void init ();
  void release ();
  bool merge (const modref_lattice &with);
  bool merge (int flags);
  bool merge_deref (const modref_lattice &with, bool ignore_stores);
  bool merge_direct_load ();
  bool merge_direct_store ();
  bool add_escape_point (gcall *call, int arg, int min_flags, bool diret);
  void dump (FILE *out, int indent = 0) const;
};

/* Lattices are saved to vectors, so keep them PODs.  */
void
modref_lattice::init ()
{
  /* All flags we track.  */
  int f = EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER
	  | EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE
	  | EAF_NO_DIRECT_READ | EAF_NO_INDIRECT_READ
	  | EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY
	  | EAF_UNUSED;
  flags = f;
  /* Check that eaf_flags_t is wide enough to hold all flags.  */
  gcc_checking_assert (f == flags);
  open = true;
  known = false;
}

/* Release memory.  */
void
modref_lattice::release ()
{
  escape_points.release ();
  propagate_to.release ();
}

/* Dump lattice to OUT; indent with INDENT spaces.  */

void
modref_lattice::dump (FILE *out, int indent) const
{
  dump_eaf_flags (out, flags);
  if (escape_points.length ())
    {
      fprintf (out, "%*sEscapes:\n", indent, "");
      for (unsigned int i = 0; i < escape_points.length (); i++)
	{
	  fprintf (out, "%*s  Arg %i (%s) min flags", indent, "",
		   escape_points[i].arg,
		   escape_points[i].direct ? "direct" : "indirect");
	  dump_eaf_flags (out, escape_points[i].min_flags, false);
	  fprintf (out, " in call ");
	  print_gimple_stmt (out, escape_points[i].call, 0);
	}
    }
}

/* Add escape point CALL, ARG, MIN_FLAGS, DIRECT.  Return false if such escape
   point exists.  */

bool
modref_lattice::add_escape_point (gcall *call, int arg, int min_flags,
				  bool direct)
{
  escape_point *ep;
  unsigned int i;

  /* If we already determined flags to be bad enough,
     we do not need to record.  */
  if ((flags & min_flags) == flags || (min_flags & EAF_UNUSED))
    return false;

  FOR_EACH_VEC_ELT (escape_points, i, ep)
    if (ep->call == call && ep->arg == arg && ep->direct == direct)
      {
	if ((ep->min_flags & min_flags) == min_flags)
	  return false;
	ep->min_flags &= min_flags;
	return true;
      }
  /* Give up if max escape points is met.  */
  if ((int)escape_points.length () > param_modref_max_escape_points)
    {
      if (dump_file)
	fprintf (dump_file, "--param modref-max-escape-points limit reached\n");
      merge (0);
      return true;
    }
  escape_point new_ep = {call, arg, min_flags, direct};
  escape_points.safe_push (new_ep);
  return true;
}

/* Merge in flags from F.  */
bool
modref_lattice::merge (int f)
{
  if (f & EAF_UNUSED)
    return false;
  /* Check that flags seems sane: if function does not read the parameter
     it can not access it indirectly.  */
  gcc_checking_assert (!(f & EAF_NO_DIRECT_READ)
		       || ((f & EAF_NO_INDIRECT_READ)
			   && (f & EAF_NO_INDIRECT_CLOBBER)
			   && (f & EAF_NO_INDIRECT_ESCAPE)
			   && (f & EAF_NOT_RETURNED_INDIRECTLY)));
  if ((flags & f) != flags)
    {
      flags &= f;
      /* Prune obvoiusly useless flags;
	 We do not have ECF_FLAGS handy which is not big problem since
	 we will do final flags cleanup before producing summary.
	 Merging should be fast so it can work well with dataflow.  */
      flags = remove_useless_eaf_flags (flags, 0, false);
      if (!flags)
	escape_points.release ();
      return true;
    }
  return false;
}

/* Merge in WITH.  Return true if anyting changed.  */

bool
modref_lattice::merge (const modref_lattice &with)
{
  if (!with.known)
    do_dataflow = true;

  bool changed = merge (with.flags);

  if (!flags)
    return changed;
  for (unsigned int i = 0; i < with.escape_points.length (); i++)
    changed |= add_escape_point (with.escape_points[i].call,
				 with.escape_points[i].arg,
				 with.escape_points[i].min_flags,
				 with.escape_points[i].direct);
  return changed;
}

/* Merge in deref of WITH.  If IGNORE_STORES is true do not consider
   stores.  Return true if anyting changed.  */

bool
modref_lattice::merge_deref (const modref_lattice &with, bool ignore_stores)
{
  if (!with.known)
    do_dataflow = true;

  bool changed = merge (deref_flags (with.flags, ignore_stores));

  if (!flags)
    return changed;
  for (unsigned int i = 0; i < with.escape_points.length (); i++)
    {
      int min_flags = with.escape_points[i].min_flags;

      if (with.escape_points[i].direct)
	min_flags = deref_flags (min_flags, ignore_stores);
      else if (ignore_stores)
	min_flags |= ignore_stores_eaf_flags;
      changed |= add_escape_point (with.escape_points[i].call,
				   with.escape_points[i].arg,
				   min_flags,
				   false);
    }
  return changed;
}

/* Merge in flags for direct load.  */

bool
modref_lattice::merge_direct_load ()
{
  return merge (~(EAF_UNUSED | EAF_NO_DIRECT_READ));
}

/* Merge in flags for direct store.  */

bool
modref_lattice::merge_direct_store ()
{
  return merge (~(EAF_UNUSED | EAF_NO_DIRECT_CLOBBER));
}

/* Analyzer of EAF flags.
   This is genrally dataflow problem over the SSA graph, however we only
   care about flags of few selected ssa names (arguments, return slot and
   static chain).  So we first call analyze_ssa_name on all relevant names
   and perform a DFS walk to discover SSA names where flags needs to be
   determined.  For acyclic graphs we try to determine final flags during
   this walk.  Once cycles or recursin depth is met we enlist SSA names
   for dataflow which is done by propagate call.

   After propagation the flags can be obtained using get_ssa_name_flags.  */

class modref_eaf_analysis
{
public:
  /* Mark NAME as relevant for analysis.  */
  void analyze_ssa_name (tree name, bool deferred = false);
  /* Dataflow slover.  */
  void propagate ();
  /* Return flags computed earlier for NAME.  */
  int get_ssa_name_flags (tree name)
  {
    int version = SSA_NAME_VERSION (name);
    gcc_checking_assert (m_lattice[version].known);
    return m_lattice[version].flags;
  }
  /* In IPA mode this will record all escape points
     determined for NAME to PARM_IDNEX.  Flags are minimal
     flags known.  */
  void record_escape_points (tree name, int parm_index, int flags);
  modref_eaf_analysis (bool ipa)
  {
    m_ipa = ipa;
    m_depth = 0;
    m_lattice.safe_grow_cleared (num_ssa_names, true);
  }
  ~modref_eaf_analysis ()
  {
    gcc_checking_assert (!m_depth);
    if (m_ipa || m_names_to_propagate.length ())
      for (unsigned int i = 0; i < num_ssa_names; i++)
	m_lattice[i].release ();
  }
private:
  /* If true, we produce analysis for IPA mode.  In this case escape points ar
     collected.  */
  bool m_ipa;
  /* Depth of recursion of analyze_ssa_name.  */
  int m_depth;
  /* Propagation lattice for individual ssa names.  */
  auto_vec<modref_lattice> m_lattice;
  auto_vec<tree> m_deferred_names;
  auto_vec<int> m_names_to_propagate;

  void merge_with_ssa_name (tree dest, tree src, bool deref);
  void merge_call_lhs_flags (gcall *call, int arg, tree name, bool direct,
			     bool deref);
};


/* Call statements may return tgeir parameters.  Consider argument number
   ARG of USE_STMT and determine flags that can needs to be cleared
   in case pointer possibly indirectly references from ARG I is returned.
   If DIRECT is true consider direct returns and if INDIRECT consider
   indirect returns.
   LATTICE, DEPTH and ipa are same as in analyze_ssa_name.
   ARG is set to -1 for static chain.  */

void
modref_eaf_analysis::merge_call_lhs_flags (gcall *call, int arg,
					   tree name, bool direct,
					   bool indirect)
{
  int index = SSA_NAME_VERSION (name);
  bool returned_directly = false;

  /* If there is no return value, no flags are affected.  */
  if (!gimple_call_lhs (call))
    return;

  /* If we know that function returns given argument and it is not ARG
     we can still be happy.  */
  if (arg >= 0)
    {
      int flags = gimple_call_return_flags (call);
      if (flags & ERF_RETURNS_ARG)
	{
	  if ((flags & ERF_RETURN_ARG_MASK) == arg)
	    returned_directly = true;
	  else
	   return;
	}
    }
  /* Make ERF_RETURNS_ARG overwrite EAF_UNUSED.  */
  if (returned_directly)
    {
      direct = true;
      indirect = false;
    }
  /* If value is not returned at all, do nothing.  */
  else if (!direct && !indirect)
    return;

  /* If return value is SSA name determine its flags.  */
  if (TREE_CODE (gimple_call_lhs (call)) == SSA_NAME)
    {
      tree lhs = gimple_call_lhs (call);
      if (direct)
	merge_with_ssa_name (name, lhs, false);
      if (indirect)
	merge_with_ssa_name (name, lhs, true);
    }
  /* In the case of memory store we can do nothing.  */
  else if (!direct)
    m_lattice[index].merge (deref_flags (0, false));
  else
    m_lattice[index].merge (0);
}

/* CALL_FLAGS are EAF_FLAGS of the argument.  Turn them
   into flags for caller, update LATTICE of corresponding
   argument if needed.  */

static int
callee_to_caller_flags (int call_flags, bool ignore_stores,
			modref_lattice &lattice)
{
  /* call_flags is about callee returning a value
     that is not the same as caller returning it.  */
  call_flags |= EAF_NOT_RETURNED_DIRECTLY
		| EAF_NOT_RETURNED_INDIRECTLY;
  if (!ignore_stores && !(call_flags & EAF_UNUSED))
    {
      /* If value escapes we are no longer able to track what happens
	 with it because we can read it from the escaped location
	 anytime.  */
      if (!(call_flags & EAF_NO_DIRECT_ESCAPE))
	lattice.merge (0);
      else if (!(call_flags & EAF_NO_INDIRECT_ESCAPE))
	lattice.merge (~(EAF_NOT_RETURNED_INDIRECTLY
			 | EAF_NO_DIRECT_READ
			 | EAF_NO_INDIRECT_READ
			 | EAF_NO_INDIRECT_CLOBBER
			 | EAF_UNUSED));
    }
  else
    call_flags |= ignore_stores_eaf_flags;
  return call_flags;
}

/* Analyze EAF flags for SSA name NAME and store result to LATTICE.
   LATTICE is an array of modref_lattices.
   DEPTH is a recursion depth used to make debug output prettier.
   If IPA is true we analyze for IPA propagation (and thus call escape points
   are processed later)  */

void
modref_eaf_analysis::analyze_ssa_name (tree name, bool deferred)
{
  imm_use_iterator ui;
  gimple *use_stmt;
  int index = SSA_NAME_VERSION (name);

  if (!deferred)
    {
      /* See if value is already computed.  */
      if (m_lattice[index].known || m_lattice[index].do_dataflow)
       return;
      if (m_lattice[index].open)
	{
	  if (dump_file)
	    fprintf (dump_file,
		     "%*sCycle in SSA graph\n",
		     m_depth * 4, "");
	  return;
	}
      /* Recursion guard.  */
      m_lattice[index].init ();
      if (m_depth == param_modref_max_depth)
	{
	  if (dump_file)
	    fprintf (dump_file,
		     "%*sMax recursion depth reached; postponing\n",
		     m_depth * 4, "");
	  m_deferred_names.safe_push (name);
	  return;
	}
    }

  if (dump_file)
    {
      fprintf (dump_file,
	       "%*sAnalyzing flags of ssa name: ", m_depth * 4, "");
      print_generic_expr (dump_file, name);
      fprintf (dump_file, "\n");
    }

  FOR_EACH_IMM_USE_STMT (use_stmt, ui, name)
    {
      if (m_lattice[index].flags == 0)
	break;
      if (is_gimple_debug (use_stmt))
	continue;
      if (dump_file)
	{
	  fprintf (dump_file, "%*s  Analyzing stmt: ", m_depth * 4, "");
	  print_gimple_stmt (dump_file, use_stmt, 0);
	}
      /* If we see a direct non-debug use, clear unused bit.
	 All dereferneces should be accounted below using deref_flags.  */
      m_lattice[index].merge (~EAF_UNUSED);

      /* Gimple return may load the return value.
	 Returning name counts as an use by tree-ssa-structalias.cc  */
      if (greturn *ret = dyn_cast <greturn *> (use_stmt))
	{
	  /* Returning through return slot is seen as memory write earlier.  */
	  if (DECL_RESULT (current_function_decl)
	      && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
	    ;
	  else if (gimple_return_retval (ret) == name)
	    m_lattice[index].merge (~(EAF_UNUSED | EAF_NOT_RETURNED_DIRECTLY
				      | EAF_NOT_RETURNED_DIRECTLY));
	  else if (memory_access_to (gimple_return_retval (ret), name))
	    {
	      m_lattice[index].merge_direct_load ();
	      m_lattice[index].merge (~(EAF_UNUSED
					| EAF_NOT_RETURNED_INDIRECTLY));
	    }
	}
      /* Account for LHS store, arg loads and flags from callee function.  */
      else if (gcall *call = dyn_cast <gcall *> (use_stmt))
	{
	  tree callee = gimple_call_fndecl (call);

	  /* IPA PTA internally it treats calling a function as "writing" to
	     the argument space of all functions the function pointer points to
	     (PR101949).  We can not drop EAF_NOCLOBBER only when ipa-pta
	     is on since that would allow propagation of this from -fno-ipa-pta
	     to -fipa-pta functions.  */
	  if (gimple_call_fn (use_stmt) == name)
	    m_lattice[index].merge (~(EAF_NO_DIRECT_CLOBBER | EAF_UNUSED));

	  /* Recursion would require bit of propagation; give up for now.  */
	  if (callee && !m_ipa && recursive_call_p (current_function_decl,
						  callee))
	    m_lattice[index].merge (0);
	  else
	    {
	      int ecf_flags = gimple_call_flags (call);
	      bool ignore_stores = ignore_stores_p (current_function_decl,
						    ecf_flags);
	      bool ignore_retval = ignore_retval_p (current_function_decl,
						    ecf_flags);

	      /* Handle *name = func (...).  */
	      if (gimple_call_lhs (call)
		  && memory_access_to (gimple_call_lhs (call), name))
		{
		  m_lattice[index].merge_direct_store ();
		  /* Return slot optimization passes address of
		     LHS to callee via hidden parameter and this
		     may make LHS to escape.  See PR 98499.  */
		  if (gimple_call_return_slot_opt_p (call)
		      && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call))))
		    {
		      int call_flags = gimple_call_retslot_flags (call);
		      bool isretslot = false;

		      if (DECL_RESULT (current_function_decl)
			  && DECL_BY_REFERENCE
				(DECL_RESULT (current_function_decl)))
			isretslot = ssa_default_def
					 (cfun,
					  DECL_RESULT (current_function_decl))
					 == name;

		      /* Passing returnslot to return slot is special because
			 not_returned and escape has same meaning.
			 However passing arg to return slot is different.  If
			 the callee's return slot is returned it means that
			 arg is written to itself which is an escape.
			 Since we do not track the memory it is written to we
			 need to give up on analysisng it.  */
		      if (!isretslot)
			{
			  if (!(call_flags & (EAF_NOT_RETURNED_DIRECTLY
					      | EAF_UNUSED)))
			    m_lattice[index].merge (0);
			  else gcc_checking_assert
				(call_flags & (EAF_NOT_RETURNED_INDIRECTLY
					       | EAF_UNUSED));
			  call_flags = callee_to_caller_flags
					   (call_flags, false,
					    m_lattice[index]);
			}
		      m_lattice[index].merge (call_flags);
		    }
		}

	      if (gimple_call_chain (call)
		  && (gimple_call_chain (call) == name))
		{
		  int call_flags = gimple_call_static_chain_flags (call);
		  if (!ignore_retval && !(call_flags & EAF_UNUSED))
		    merge_call_lhs_flags
			 (call, -1, name,
			  !(call_flags & EAF_NOT_RETURNED_DIRECTLY),
			  !(call_flags & EAF_NOT_RETURNED_INDIRECTLY));
		  call_flags = callee_to_caller_flags
				   (call_flags, ignore_stores,
				    m_lattice[index]);
		  if (!(ecf_flags & (ECF_CONST | ECF_NOVOPS)))
		    m_lattice[index].merge (call_flags);
		}

	      /* Process internal functions and right away.  */
	      bool record_ipa = m_ipa && !gimple_call_internal_p (call);

	      /* Handle all function parameters.  */
	      for (unsigned i = 0;
		   i < gimple_call_num_args (call)
		   && m_lattice[index].flags; i++)
		/* Name is directly passed to the callee.  */
		if (gimple_call_arg (call, i) == name)
		  {
		    int call_flags = gimple_call_arg_flags (call, i);
		    if (!ignore_retval)
		      merge_call_lhs_flags
			      (call, i, name,
			       !(call_flags & (EAF_NOT_RETURNED_DIRECTLY
					       | EAF_UNUSED)),
			       !(call_flags & (EAF_NOT_RETURNED_INDIRECTLY
					       | EAF_UNUSED)));
		    if (!(ecf_flags & (ECF_CONST | ECF_NOVOPS)))
		      {
			call_flags = callee_to_caller_flags
					 (call_flags, ignore_stores,
					  m_lattice[index]);
			if (!record_ipa)
			  m_lattice[index].merge (call_flags);
			else
			  m_lattice[index].add_escape_point (call, i,
							   call_flags, true);
		      }
		  }
		/* Name is dereferenced and passed to a callee.  */
		else if (memory_access_to (gimple_call_arg (call, i), name))
		  {
		    int call_flags = deref_flags
			    (gimple_call_arg_flags (call, i), ignore_stores);
		    if (!ignore_retval && !(call_flags & EAF_UNUSED)
			&& !(call_flags & EAF_NOT_RETURNED_DIRECTLY)
			&& !(call_flags & EAF_NOT_RETURNED_INDIRECTLY))
		      merge_call_lhs_flags (call, i, name, false, true);
		    if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
		      m_lattice[index].merge_direct_load ();
		    else
		      {
			call_flags = callee_to_caller_flags
					 (call_flags, ignore_stores,
					  m_lattice[index]);
			if (!record_ipa)
			  m_lattice[index].merge (call_flags);
			else
			  m_lattice[index].add_escape_point (call, i,
							     call_flags, false);
		      }
		  }
	    }
	}
      else if (gimple_assign_load_p (use_stmt))
	{
	  gassign *assign = as_a <gassign *> (use_stmt);
	  /* Memory to memory copy.  */
	  if (gimple_store_p (assign))
	    {
	      /* Handle *lhs = *name.

		 We do not track memory locations, so assume that value
		 is used arbitrarily.  */
	      if (memory_access_to (gimple_assign_rhs1 (assign), name))
		m_lattice[index].merge (deref_flags (0, false));
	      /* Handle *name = *exp.  */
	      else if (memory_access_to (gimple_assign_lhs (assign), name))
		m_lattice[index].merge_direct_store ();
	    }
	  /* Handle lhs = *name.  */
	  else if (memory_access_to (gimple_assign_rhs1 (assign), name))
	    {
	      tree lhs = gimple_assign_lhs (assign);
	      merge_with_ssa_name (name, lhs, true);
	    }
	}
      else if (gimple_store_p (use_stmt))
	{
	  gassign *assign = dyn_cast <gassign *> (use_stmt);

	  /* Handle *lhs = name.  */
	  if (assign && gimple_assign_rhs1 (assign) == name)
	    {
	      if (dump_file)
		fprintf (dump_file, "%*s  ssa name saved to memory\n",
			 m_depth * 4, "");
	      m_lattice[index].merge (0);
	    }
	  /* Handle *name = exp.  */
	  else if (assign
		   && memory_access_to (gimple_assign_lhs (assign), name))
	    {
	      /* In general we can not ignore clobbers because they are
		 barriers for code motion, however after inlining it is safe to
		 do because local optimization passes do not consider clobbers
		 from other functions.
		 Similar logic is in ipa-pure-const.cc.  */
	      if (!cfun->after_inlining || !gimple_clobber_p (assign))
		m_lattice[index].merge_direct_store ();
	    }
	  /* ASM statements etc.  */
	  else if (!assign)
	    {
	      if (dump_file)
		fprintf (dump_file, "%*s  Unhandled store\n", m_depth * 4, "");
	      m_lattice[index].merge (0);
	    }
	}
      else if (gassign *assign = dyn_cast <gassign *> (use_stmt))
	{
	  enum tree_code code = gimple_assign_rhs_code (assign);

	  /* See if operation is a merge as considered by
	     tree-ssa-structalias.cc:find_func_aliases.  */
	  if (!truth_value_p (code)
	      && code != POINTER_DIFF_EXPR
	      && (code != POINTER_PLUS_EXPR
		  || gimple_assign_rhs1 (assign) == name))
	    {
	      tree lhs = gimple_assign_lhs (assign);
	      merge_with_ssa_name (name, lhs, false);
	    }
	}
      else if (gphi *phi = dyn_cast <gphi *> (use_stmt))
	{
	  tree result = gimple_phi_result (phi);
	  merge_with_ssa_name (name, result, false);
	}
      /* Conditions are not considered escape points
	 by tree-ssa-structalias.  */
      else if (gimple_code (use_stmt) == GIMPLE_COND)
	;
      else
	{
	  if (dump_file)
	    fprintf (dump_file, "%*s  Unhandled stmt\n", m_depth * 4, "");
	  m_lattice[index].merge (0);
	}

      if (dump_file)
	{
	  fprintf (dump_file, "%*s  current flags of ", m_depth * 4, "");
	  print_generic_expr (dump_file, name);
	  m_lattice[index].dump (dump_file, m_depth * 4 + 4);
	}
    }
  if (dump_file)
    {
      fprintf (dump_file, "%*sflags of ssa name ", m_depth * 4, "");
      print_generic_expr (dump_file, name);
      m_lattice[index].dump (dump_file, m_depth * 4 + 2);
    }
  m_lattice[index].open = false;
  if (!m_lattice[index].do_dataflow)
    m_lattice[index].known = true;
}

/* Propagate info from SRC to DEST.  If DEREF it true, assume that SRC
   is dereferenced.  */

void
modref_eaf_analysis::merge_with_ssa_name (tree dest, tree src, bool deref)
{
  int index = SSA_NAME_VERSION (dest);
  int src_index = SSA_NAME_VERSION (src);

  /* Merging lattice with itself is a no-op.  */
  if (!deref && src == dest)
    return;

  m_depth++;
  analyze_ssa_name (src);
  m_depth--;
  if (deref)
    m_lattice[index].merge_deref (m_lattice[src_index], false);
  else
    m_lattice[index].merge (m_lattice[src_index]);

  /* If we failed to produce final solution add an edge to the dataflow
     graph.  */
  if (!m_lattice[src_index].known)
    {
      modref_lattice::propagate_edge e = {index, deref};

      if (!m_lattice[src_index].propagate_to.length ())
	m_names_to_propagate.safe_push (src_index);
      m_lattice[src_index].propagate_to.safe_push (e);
      m_lattice[src_index].changed = true;
      m_lattice[src_index].do_dataflow = true;
      if (dump_file)
	fprintf (dump_file,
		 "%*sWill propgate from ssa_name %i to %i%s\n",
		 m_depth * 4 + 4,
		 "", src_index, index, deref ? " (deref)" : "");
    }
}

/* In the case we deferred some SSA names, reprocess them.  In the case some
   dataflow edges were introduced, do the actual iterative dataflow.  */

void
modref_eaf_analysis::propagate ()
{
  int iterations = 0;
  size_t i;
  int index;
  bool changed = true;

  while (m_deferred_names.length ())
    {
      tree name = m_deferred_names.pop ();
      if (dump_file)
	fprintf (dump_file, "Analyzing deferred SSA name\n");
      analyze_ssa_name (name, true);
    }

  if (!m_names_to_propagate.length ())
    return;
  if (dump_file)
    fprintf (dump_file, "Propagating EAF flags\n");

  /* Compute reverse postorder.  */
  auto_vec <int> rpo;
  struct stack_entry
  {
    int name;
    unsigned pos;
  };
  auto_vec <struct stack_entry> stack;
  int pos = m_names_to_propagate.length () - 1;

  rpo.safe_grow (m_names_to_propagate.length (), true);
  stack.reserve_exact (m_names_to_propagate.length ());

  /* We reuse known flag for RPO DFS walk bookeeping.  */
  if (flag_checking)
    FOR_EACH_VEC_ELT (m_names_to_propagate, i, index)
      gcc_assert (!m_lattice[index].known && m_lattice[index].changed);

  FOR_EACH_VEC_ELT (m_names_to_propagate, i, index)
    {
      if (!m_lattice[index].known)
	{
	  stack_entry e = {index, 0};

	  stack.quick_push (e);
	  m_lattice[index].known = true;
	}
      while (stack.length ())
	{
	  bool found = false;
	  int index1 = stack.last ().name;

	  while (stack.last ().pos < m_lattice[index1].propagate_to.length ())
	    {
	      int index2 = m_lattice[index1]
		      .propagate_to[stack.last ().pos].ssa_name;

	      stack.last ().pos++;
	      if (!m_lattice[index2].known
		  && m_lattice[index2].propagate_to.length ())
		{
		  stack_entry e = {index2, 0};

		  stack.quick_push (e);
		  m_lattice[index2].known = true;
		  found = true;
		  break;
		}
	    }
	  if (!found
	      && stack.last ().pos == m_lattice[index1].propagate_to.length ())
	    {
	      rpo[pos--] = index1;
	      stack.pop ();
	    }
	}
    }

  /* Perform itrative dataflow.  */
  while (changed)
    {
      changed = false;
      iterations++;
      if (dump_file)
	fprintf (dump_file, " iteration %i\n", iterations);
      FOR_EACH_VEC_ELT (rpo, i, index)
	{
	  if (m_lattice[index].changed)
	    {
	      size_t j;

	      m_lattice[index].changed = false;
	      if (dump_file)
		fprintf (dump_file, "  Visiting ssa name %i\n", index);
	      for (j = 0; j < m_lattice[index].propagate_to.length (); j++)
		{
		  bool ch;
		  int target = m_lattice[index].propagate_to[j].ssa_name;
		  bool deref = m_lattice[index].propagate_to[j].deref;

		  if (dump_file)
		    fprintf (dump_file, "   Propagating flags of ssa name"
			     " %i to %i%s\n",
			     index, target, deref ? " (deref)" : "");
		  m_lattice[target].known = true;
		  if (!m_lattice[index].propagate_to[j].deref)
		    ch = m_lattice[target].merge (m_lattice[index]);
		  else
		    ch = m_lattice[target].merge_deref (m_lattice[index],
							false);
		  if (!ch)
		    continue;
		  if (dump_file)
		    {
		      fprintf (dump_file, "   New lattice: ");
		      m_lattice[target].dump (dump_file);
		    }
		  changed = true;
		  m_lattice[target].changed = true;
		}
	    }
	}
    }
  if (dump_file)
    fprintf (dump_file, "EAF flags propagated in %i iterations\n", iterations);
}

/* Record escape points of PARM_INDEX according to LATTICE.  */

void
modref_eaf_analysis::record_escape_points (tree name, int parm_index, int flags)
{
  modref_lattice &lattice = m_lattice[SSA_NAME_VERSION (name)];

  if (lattice.escape_points.length ())
    {
      escape_point *ep;
      unsigned int ip;
      cgraph_node *node = cgraph_node::get (current_function_decl);

      gcc_assert (m_ipa);
      FOR_EACH_VEC_ELT (lattice.escape_points, ip, ep)
	if ((ep->min_flags & flags) != flags)
	  {
	    cgraph_edge *e = node->get_edge (ep->call);
	    struct escape_entry ee = {parm_index, ep->arg,
				      ep->min_flags, ep->direct};

	    escape_summaries->get_create (e)->esc.safe_push (ee);
	  }
    }
}

/* Determine EAF flags for function parameters
   and fill in SUMMARY/SUMMARY_LTO.  If IPA is true work in IPA mode
   where we also collect scape points.
   PAST_FLAGS, PAST_RETSLOT_FLAGS, PAST_STATIC_CHAIN_FLAGS can be
   used to preserve flags from prevoius (IPA) run for cases where
   late optimizations changed code in a way we can no longer analyze
   it easily.  */

static void
analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
	       bool ipa, vec<eaf_flags_t> &past_flags,
	       int past_retslot_flags, int past_static_chain_flags)
{
  unsigned int parm_index = 0;
  unsigned int count = 0;
  int ecf_flags = flags_from_decl_or_type (current_function_decl);
  tree retslot = NULL;
  tree static_chain = NULL;

  /* If there is return slot, look up its SSA name.  */
  if (DECL_RESULT (current_function_decl)
      && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
    retslot = ssa_default_def (cfun, DECL_RESULT (current_function_decl));
  if (cfun->static_chain_decl)
    static_chain = ssa_default_def (cfun, cfun->static_chain_decl);

  for (tree parm = DECL_ARGUMENTS (current_function_decl); parm;
       parm = TREE_CHAIN (parm))
    count++;

  if (!count && !retslot && !static_chain)
    return;

  modref_eaf_analysis eaf_analysis (ipa);

  /* Determine all SSA names we need to know flags for.  */
  for (tree parm = DECL_ARGUMENTS (current_function_decl); parm;
       parm = TREE_CHAIN (parm))
    {
      tree name = ssa_default_def (cfun, parm);
      if (name)
	eaf_analysis.analyze_ssa_name (name);
    }
  if (retslot)
    eaf_analysis.analyze_ssa_name (retslot);
  if (static_chain)
    eaf_analysis.analyze_ssa_name (static_chain);

  /* Do the dataflow.  */
  eaf_analysis.propagate ();

  tree attr = lookup_attribute ("fn spec",
				TYPE_ATTRIBUTES
				  (TREE_TYPE (current_function_decl)));
  attr_fnspec fnspec (attr
		      ? TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))
		      : "");


  /* Store results to summaries.  */
  for (tree parm = DECL_ARGUMENTS (current_function_decl); parm; parm_index++,
       parm = TREE_CHAIN (parm))
    {
      tree name = ssa_default_def (cfun, parm);
      if (!name || has_zero_uses (name))
	{
	  /* We do not track non-SSA parameters,
	     but we want to track unused gimple_regs.  */
	  if (!is_gimple_reg (parm))
	    continue;
	  if (summary)
	    {
	      if (parm_index >= summary->arg_flags.length ())
		summary->arg_flags.safe_grow_cleared (count, true);
	      summary->arg_flags[parm_index] = EAF_UNUSED;
	    }
	  else if (summary_lto)
	    {
	      if (parm_index >= summary_lto->arg_flags.length ())
		summary_lto->arg_flags.safe_grow_cleared (count, true);
	      summary_lto->arg_flags[parm_index] = EAF_UNUSED;
	    }
	  continue;
	}
      int flags = eaf_analysis.get_ssa_name_flags (name);
      int attr_flags = fnspec.arg_eaf_flags (parm_index);

      if (dump_file && (flags | attr_flags) != flags && !(flags & EAF_UNUSED))
	{
	  fprintf (dump_file,
		   "  Flags for param %i combined with fnspec flags:",
		   (int)parm_index);
	  dump_eaf_flags (dump_file, attr_flags, false);
	  fprintf (dump_file, " determined: ");
	  dump_eaf_flags (dump_file, flags, true);
	}
      flags |= attr_flags;

      /* Eliminate useless flags so we do not end up storing unnecessary
	 summaries.  */

      flags = remove_useless_eaf_flags
		 (flags, ecf_flags,
		  VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
      if (past_flags.length () > parm_index)
	{
	  int past = past_flags[parm_index];
	  past = remove_useless_eaf_flags
		     (past, ecf_flags,
		      VOID_TYPE_P (TREE_TYPE
			  (TREE_TYPE (current_function_decl))));
	  if (dump_file && (flags | past) != flags && !(flags & EAF_UNUSED))
	    {
	      fprintf (dump_file,
		       "  Flags for param %i combined with IPA pass:",
		       (int)parm_index);
	      dump_eaf_flags (dump_file, past, false);
	      fprintf (dump_file, " determined: ");
	      dump_eaf_flags (dump_file, flags, true);
	    }
	  if (!(flags & EAF_UNUSED))
	    flags |= past;
	}

      if (flags)
	{
	  if (summary)
	    {
	      if (parm_index >= summary->arg_flags.length ())
		summary->arg_flags.safe_grow_cleared (count, true);
	      summary->arg_flags[parm_index] = flags;
	    }
	  else if (summary_lto)
	    {
	      if (parm_index >= summary_lto->arg_flags.length ())
		summary_lto->arg_flags.safe_grow_cleared (count, true);
	      summary_lto->arg_flags[parm_index] = flags;
	    }
	  eaf_analysis.record_escape_points (name, parm_index, flags);
	}
    }
  if (retslot)
    {
      int flags = eaf_analysis.get_ssa_name_flags (retslot);
      int past = past_retslot_flags;

      flags = remove_useless_eaf_flags (flags, ecf_flags, false);
      past = remove_useless_eaf_flags
		 (past, ecf_flags,
		  VOID_TYPE_P (TREE_TYPE
		      (TREE_TYPE (current_function_decl))));
      if (dump_file && (flags | past) != flags && !(flags & EAF_UNUSED))
	{
	  fprintf (dump_file,
		   "  Retslot flags combined with IPA pass:");
	  dump_eaf_flags (dump_file, past, false);
	  fprintf (dump_file, " determined: ");
	  dump_eaf_flags (dump_file, flags, true);
	}
      if (!(flags & EAF_UNUSED))
	flags |= past;
      if (flags)
	{
	  if (summary)
	    summary->retslot_flags = flags;
	  if (summary_lto)
	    summary_lto->retslot_flags = flags;
	  eaf_analysis.record_escape_points (retslot,
					     MODREF_RETSLOT_PARM, flags);
	}
    }
  if (static_chain)
    {
      int flags = eaf_analysis.get_ssa_name_flags (static_chain);
      int past = past_static_chain_flags;

      flags = remove_useless_eaf_flags (flags, ecf_flags, false);
      past = remove_useless_eaf_flags
		 (past, ecf_flags,
		  VOID_TYPE_P (TREE_TYPE
		      (TREE_TYPE (current_function_decl))));
      if (dump_file && (flags | past) != flags && !(flags & EAF_UNUSED))
	{
	  fprintf (dump_file,
		   "  Static chain flags combined with IPA pass:");
	  dump_eaf_flags (dump_file, past, false);
	  fprintf (dump_file, " determined: ");
	  dump_eaf_flags (dump_file, flags, true);
	}
      if (!(flags & EAF_UNUSED))
	flags |= past;
      if (flags)
	{
	  if (summary)
	    summary->static_chain_flags = flags;
	  if (summary_lto)
	    summary_lto->static_chain_flags = flags;
	  eaf_analysis.record_escape_points (static_chain,
					     MODREF_STATIC_CHAIN_PARM,
					     flags);
	}
    }
}

/* Analyze function.  IPA indicates whether we're running in local mode
   (false) or the IPA mode (true).
   Return true if fixup cfg is needed after the pass.  */

static bool
analyze_function (bool ipa)
{
  bool fixup_cfg = false;
  if (dump_file)
    fprintf (dump_file, "\n\nmodref analyzing '%s' (ipa=%i)%s%s\n",
	     cgraph_node::get (current_function_decl)->dump_name (), ipa,
	     TREE_READONLY (current_function_decl) ? " (const)" : "",
	     DECL_PURE_P (current_function_decl) ? " (pure)" : "");

  /* Don't analyze this function if it's compiled with -fno-strict-aliasing.  */
  if (!flag_ipa_modref
      || lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl)))
    return false;

  /* Compute no-LTO summaries when local optimization is going to happen.  */
  bool nolto = (!ipa || ((!flag_lto || flag_fat_lto_objects) && !in_lto_p)
		|| (in_lto_p && !flag_wpa
		    && flag_incremental_link != INCREMENTAL_LINK_LTO));
  /* Compute LTO when LTO streaming is going to happen.  */
  bool lto = ipa && ((flag_lto && !in_lto_p)
		     || flag_wpa
		     || flag_incremental_link == INCREMENTAL_LINK_LTO);
  cgraph_node *fnode = cgraph_node::get (current_function_decl);

  modref_summary *summary = NULL;
  modref_summary_lto *summary_lto = NULL;

  bool past_flags_known = false;
  auto_vec <eaf_flags_t> past_flags;
  int past_retslot_flags = 0;
  int past_static_chain_flags = 0;

  /* Initialize the summary.
     If we run in local mode there is possibly pre-existing summary from
     IPA pass.  Dump it so it is easy to compare if mod-ref info has
     improved.  */
  if (!ipa)
    {
      if (!optimization_summaries)
	optimization_summaries = modref_summaries::create_ggc (symtab);
      else /* Remove existing summary if we are re-running the pass.  */
	{
	  summary = optimization_summaries->get (fnode);
	  if (summary != NULL
	      && summary->loads)
	    {
	      if (dump_file)
		{
		  fprintf (dump_file, "Past summary:\n");
		  optimization_summaries->get (fnode)->dump (dump_file);
		}
	      past_flags.reserve_exact (summary->arg_flags.length ());
	      past_flags.splice (summary->arg_flags);
	      past_retslot_flags = summary->retslot_flags;
	      past_static_chain_flags = summary->static_chain_flags;
	      past_flags_known = true;
	    }
	  optimization_summaries->remove (fnode);
	}
      summary = optimization_summaries->get_create (fnode);
      gcc_checking_assert (nolto && !lto);
    }
  /* In IPA mode we analyze every function precisely once.  Assert that.  */
  else
    {
      if (nolto)
	{
	  if (!summaries)
	    summaries = modref_summaries::create_ggc (symtab);
	  else
	    summaries->remove (fnode);
	  summary = summaries->get_create (fnode);
	}
      if (lto)
	{
	  if (!summaries_lto)
	    summaries_lto = modref_summaries_lto::create_ggc (symtab);
	  else
	    summaries_lto->remove (fnode);
	  summary_lto = summaries_lto->get_create (fnode);
	}
      if (!fnspec_summaries)
	fnspec_summaries = new fnspec_summaries_t (symtab);
      if (!escape_summaries)
	escape_summaries = new escape_summaries_t (symtab);
     }


  /* Create and initialize summary for F.
     Note that summaries may be already allocated from previous
     run of the pass.  */
  if (nolto)
    {
      gcc_assert (!summary->loads);
      summary->loads = modref_records::create_ggc ();
      gcc_assert (!summary->stores);
      summary->stores = modref_records::create_ggc ();
      summary->writes_errno = false;
      summary->side_effects = false;
      summary->nondeterministic = false;
      summary->calls_interposable = false;
    }
  if (lto)
    {
      gcc_assert (!summary_lto->loads);
      summary_lto->loads = modref_records_lto::create_ggc ();
      gcc_assert (!summary_lto->stores);
      summary_lto->stores = modref_records_lto::create_ggc ();
      summary_lto->writes_errno = false;
      summary_lto->side_effects = false;
      summary_lto->nondeterministic = false;
      summary_lto->calls_interposable = false;
    }

  analyze_parms (summary, summary_lto, ipa,
		 past_flags, past_retslot_flags, past_static_chain_flags);

  {
    modref_access_analysis analyzer (ipa, summary, summary_lto);
    analyzer.analyze ();
  }

  if (!ipa && flag_ipa_pure_const)
    {
      if (!summary->stores->every_base && !summary->stores->bases
	  && !summary->nondeterministic)
	{
	  if (!summary->loads->every_base && !summary->loads->bases
	      && !summary->calls_interposable)
	    fixup_cfg = ipa_make_function_const (fnode,
						 summary->side_effects, true);
	  else
	    fixup_cfg = ipa_make_function_pure (fnode,
						summary->side_effects, true);
	}
    }
  int ecf_flags = flags_from_decl_or_type (current_function_decl);
  if (summary && !summary->useful_p (ecf_flags))
    {
      if (!ipa)
	optimization_summaries->remove (fnode);
      else
	summaries->remove (fnode);
      summary = NULL;
    }
  if (summary)
    summary->finalize (current_function_decl);
  if (summary_lto && !summary_lto->useful_p (ecf_flags))
    {
      summaries_lto->remove (fnode);
      summary_lto = NULL;
    }

  if (ipa && !summary && !summary_lto)
    remove_modref_edge_summaries (fnode);

  if (dump_file)
    {
      fprintf (dump_file, " - modref done with result: tracked.\n");
      if (summary)
	summary->dump (dump_file);
      if (summary_lto)
	summary_lto->dump (dump_file);
      dump_modref_edge_summaries (dump_file, fnode, 2);
      /* To simplify debugging, compare IPA and local solutions.  */
      if (past_flags_known && summary)
	{
	  size_t len = summary->arg_flags.length ();

	  if (past_flags.length () > len)
	    len = past_flags.length ();
	  for (size_t i = 0; i < len; i++)
	    {
	      int old_flags = i < past_flags.length () ? past_flags[i] : 0;
	      int new_flags = i < summary->arg_flags.length ()
			      ? summary->arg_flags[i] : 0;
	      old_flags = remove_useless_eaf_flags
		(old_flags, flags_from_decl_or_type (current_function_decl),
		 VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
	      if (old_flags != new_flags)
		{
		  if ((old_flags & ~new_flags) == 0
		      || (new_flags & EAF_UNUSED))
		    fprintf (dump_file, "  Flags for param %i improved:",
			     (int)i);
		  else
		    gcc_unreachable ();
		  dump_eaf_flags (dump_file, old_flags, false);
		  fprintf (dump_file, " -> ");
		  dump_eaf_flags (dump_file, new_flags, true);
		}
	    }
	  past_retslot_flags = remove_useless_eaf_flags
		(past_retslot_flags,
		 flags_from_decl_or_type (current_function_decl),
		 VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
	  if (past_retslot_flags != summary->retslot_flags)
	    {
	      if ((past_retslot_flags & ~summary->retslot_flags) == 0
		  || (summary->retslot_flags & EAF_UNUSED))
		fprintf (dump_file, "  Flags for retslot improved:");
	      else
		gcc_unreachable ();
	      dump_eaf_flags (dump_file, past_retslot_flags, false);
	      fprintf (dump_file, " -> ");
	      dump_eaf_flags (dump_file, summary->retslot_flags, true);
	    }
	  past_static_chain_flags = remove_useless_eaf_flags
		(past_static_chain_flags,
		 flags_from_decl_or_type (current_function_decl),
		 VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
	  if (past_static_chain_flags != summary->static_chain_flags)
	    {
	      if ((past_static_chain_flags & ~summary->static_chain_flags) == 0
		  || (summary->static_chain_flags & EAF_UNUSED))
		fprintf (dump_file, "  Flags for static chain improved:");
	      else
		gcc_unreachable ();
	      dump_eaf_flags (dump_file, past_static_chain_flags, false);
	      fprintf (dump_file, " -> ");
	      dump_eaf_flags (dump_file, summary->static_chain_flags, true);
	    }
	}
      else if (past_flags_known && !summary)
	{
	  for (size_t i = 0; i < past_flags.length (); i++)
	    {
	      int old_flags = past_flags[i];
	      old_flags = remove_useless_eaf_flags
		(old_flags, flags_from_decl_or_type (current_function_decl),
		 VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
	      if (old_flags)
		{
		  fprintf (dump_file, "  Flags for param %i worsened:",
			   (int)i);
		  dump_eaf_flags (dump_file, old_flags, false);
		  fprintf (dump_file, " -> \n");
		}
	    }
	  past_retslot_flags = remove_useless_eaf_flags
		(past_retslot_flags,
		 flags_from_decl_or_type (current_function_decl),
		 VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
	  if (past_retslot_flags)
	    {
	      fprintf (dump_file, "  Flags for retslot worsened:");
	      dump_eaf_flags (dump_file, past_retslot_flags, false);
	      fprintf (dump_file, " ->\n");
	    }
	  past_static_chain_flags = remove_useless_eaf_flags
		(past_static_chain_flags,
		 flags_from_decl_or_type (current_function_decl),
		 VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
	  if (past_static_chain_flags)
	    {
	      fprintf (dump_file, "  Flags for static chain worsened:");
	      dump_eaf_flags (dump_file, past_static_chain_flags, false);
	      fprintf (dump_file, " ->\n");
	    }
	}
    }
  return fixup_cfg;
}

/* Callback for generate_summary.  */

static void
modref_generate (void)
{
  struct cgraph_node *node;
  FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
    {
      function *f = DECL_STRUCT_FUNCTION (node->decl);
      if (!f)
	continue;
      push_cfun (f);
      analyze_function (true);
      pop_cfun ();
    }
}

}  /* ANON namespace.  */

/* Debugging helper.  */

void
debug_eaf_flags (int flags)
{
   dump_eaf_flags (stderr, flags, true);
}

/* Called when a new function is inserted to callgraph late.  */

void
modref_summaries::insert (struct cgraph_node *node, modref_summary *)
{
  /* Local passes ought to be executed by the pass manager.  */
  if (this == optimization_summaries)
    {
      optimization_summaries->remove (node);
      return;
    }
  if (!DECL_STRUCT_FUNCTION (node->decl)
      || !opt_for_fn (node->decl, flag_ipa_modref))
    {
      summaries->remove (node);
      return;
    }
  push_cfun (DECL_STRUCT_FUNCTION (node->decl));
  analyze_function (true);
  pop_cfun ();
}

/* Called when a new function is inserted to callgraph late.  */

void
modref_summaries_lto::insert (struct cgraph_node *node, modref_summary_lto *)
{
  /* We do not support adding new function when IPA information is already
     propagated.  This is done only by SIMD cloning that is not very
     critical.  */
  if (!DECL_STRUCT_FUNCTION (node->decl)
      || !opt_for_fn (node->decl, flag_ipa_modref)
      || propagated)
    {
      summaries_lto->remove (node);
      return;
    }
  push_cfun (DECL_STRUCT_FUNCTION (node->decl));
  analyze_function (true);
  pop_cfun ();
}

/* Called when new clone is inserted to callgraph late.  */

void
modref_summaries::duplicate (cgraph_node *, cgraph_node *dst,
			     modref_summary *src_data,
			     modref_summary *dst_data)
{
  /* Do not duplicate optimization summaries; we do not handle parameter
     transforms on them.  */
  if (this == optimization_summaries)
    {
      optimization_summaries->remove (dst);
      return;
    }
  dst_data->stores = modref_records::create_ggc ();
  dst_data->stores->copy_from (src_data->stores);
  dst_data->loads = modref_records::create_ggc ();
  dst_data->loads->copy_from (src_data->loads);
  dst_data->kills.reserve_exact (src_data->kills.length ());
  dst_data->kills.splice (src_data->kills);
  dst_data->writes_errno = src_data->writes_errno;
  dst_data->side_effects = src_data->side_effects;
  dst_data->nondeterministic = src_data->nondeterministic;
  dst_data->calls_interposable = src_data->calls_interposable;
  if (src_data->arg_flags.length ())
    dst_data->arg_flags = src_data->arg_flags.copy ();
  dst_data->retslot_flags = src_data->retslot_flags;
  dst_data->static_chain_flags = src_data->static_chain_flags;
}

/* Called when new clone is inserted to callgraph late.  */

void
modref_summaries_lto::duplicate (cgraph_node *, cgraph_node *,
				 modref_summary_lto *src_data,
				 modref_summary_lto *dst_data)
{
  /* Be sure that no further cloning happens after ipa-modref.  If it does
     we will need to update signatures for possible param changes.  */
  gcc_checking_assert (!((modref_summaries_lto *)summaries_lto)->propagated);
  dst_data->stores = modref_records_lto::create_ggc ();
  dst_data->stores->copy_from (src_data->stores);
  dst_data->loads = modref_records_lto::create_ggc ();
  dst_data->loads->copy_from (src_data->loads);
  dst_data->kills.reserve_exact (src_data->kills.length ());
  dst_data->kills.splice (src_data->kills);
  dst_data->writes_errno = src_data->writes_errno;
  dst_data->side_effects = src_data->side_effects;
  dst_data->nondeterministic = src_data->nondeterministic;
  dst_data->calls_interposable = src_data->calls_interposable;
  if (src_data->arg_flags.length ())
    dst_data->arg_flags = src_data->arg_flags.copy ();
  dst_data->retslot_flags = src_data->retslot_flags;
  dst_data->static_chain_flags = src_data->static_chain_flags;
}

namespace
{
/* Definition of the modref pass on GIMPLE.  */
const pass_data pass_data_modref = {
  GIMPLE_PASS,
  "modref",
  OPTGROUP_IPA,
  TV_TREE_MODREF,
  (PROP_cfg | PROP_ssa),
  0,
  0,
  0,
  0,
};

class pass_modref : public gimple_opt_pass
{
  public:
    pass_modref (gcc::context *ctxt)
	: gimple_opt_pass (pass_data_modref, ctxt) {}

    /* opt_pass methods: */
    opt_pass *clone ()
    {
      return new pass_modref (m_ctxt);
    }
    virtual bool gate (function *)
    {
      return flag_ipa_modref;
    }
    virtual unsigned int execute (function *);
};

/* Encode TT to the output block OB using the summary streaming API.  */

static void
write_modref_records (modref_records_lto *tt, struct output_block *ob)
{
  streamer_write_uhwi (ob, tt->every_base);
  streamer_write_uhwi (ob, vec_safe_length (tt->bases));
  for (auto base_node : tt->bases)
    {
      stream_write_tree (ob, base_node->base, true);

      streamer_write_uhwi (ob, base_node->every_ref);
      streamer_write_uhwi (ob, vec_safe_length (base_node->refs));

      for (auto ref_node : base_node->refs)
	{
	  stream_write_tree (ob, ref_node->ref, true);
	  streamer_write_uhwi (ob, ref_node->every_access);
	  streamer_write_uhwi (ob, vec_safe_length (ref_node->accesses));

	  for (auto access_node : ref_node->accesses)
	    access_node.stream_out (ob);
	}
    }
}

/* Read a modref_tree from the input block IB using the data from DATA_IN.
   This assumes that the tree was encoded using write_modref_tree.
   Either nolto_ret or lto_ret is initialized by the tree depending whether
   LTO streaming is expected or not.  */

static void
read_modref_records (tree decl,
		     lto_input_block *ib, struct data_in *data_in,
		     modref_records **nolto_ret,
		     modref_records_lto **lto_ret)
{
  size_t max_bases = opt_for_fn (decl, param_modref_max_bases);
  size_t max_refs = opt_for_fn (decl, param_modref_max_refs);
  size_t max_accesses = opt_for_fn (decl, param_modref_max_accesses);

  if (lto_ret)
    *lto_ret = modref_records_lto::create_ggc ();
  if (nolto_ret)
    *nolto_ret = modref_records::create_ggc ();
  gcc_checking_assert (lto_ret || nolto_ret);

  size_t every_base = streamer_read_uhwi (ib);
  size_t nbase = streamer_read_uhwi (ib);

  gcc_assert (!every_base || nbase == 0);
  if (every_base)
    {
      if (nolto_ret)
	(*nolto_ret)->collapse ();
      if (lto_ret)
	(*lto_ret)->collapse ();
    }
  for (size_t i = 0; i < nbase; i++)
    {
      tree base_tree = stream_read_tree (ib, data_in);
      modref_base_node <alias_set_type> *nolto_base_node = NULL;
      modref_base_node <tree> *lto_base_node = NULL;

      /* At stream in time we have LTO alias info.  Check if we streamed in
	 something obviously unnecessary.  Do not glob types by alias sets;
	 it is not 100% clear that ltrans types will get merged same way.
	 Types may get refined based on ODR type conflicts.  */
      if (base_tree && !get_alias_set (base_tree))
	{
	  if (dump_file)
	    {
	      fprintf (dump_file, "Streamed in alias set 0 type ");
	      print_generic_expr (dump_file, base_tree);
	      fprintf (dump_file, "\n");
	    }
	  base_tree = NULL;
	}

      if (nolto_ret)
	nolto_base_node = (*nolto_ret)->insert_base (base_tree
						     ? get_alias_set (base_tree)
						     : 0, 0, INT_MAX);
      if (lto_ret)
	lto_base_node = (*lto_ret)->insert_base (base_tree, 0, max_bases);
      size_t every_ref = streamer_read_uhwi (ib);
      size_t nref = streamer_read_uhwi (ib);

      gcc_assert (!every_ref || nref == 0);
      if (every_ref)
	{
	  if (nolto_base_node)
	    nolto_base_node->collapse ();
	  if (lto_base_node)
	    lto_base_node->collapse ();
	}
      for (size_t j = 0; j < nref; j++)
	{
	  tree ref_tree = stream_read_tree (ib, data_in);

	  if (ref_tree && !get_alias_set (ref_tree))
	    {
	      if (dump_file)
		{
		  fprintf (dump_file, "Streamed in alias set 0 type ");
		  print_generic_expr (dump_file, ref_tree);
		  fprintf (dump_file, "\n");
		}
	      ref_tree = NULL;
	    }

	  modref_ref_node <alias_set_type> *nolto_ref_node = NULL;
	  modref_ref_node <tree> *lto_ref_node = NULL;

	  if (nolto_base_node)
	    nolto_ref_node
	      = nolto_base_node->insert_ref (ref_tree
					     ? get_alias_set (ref_tree) : 0,
					     max_refs);
	  if (lto_base_node)
	    lto_ref_node = lto_base_node->insert_ref (ref_tree, max_refs);

	  size_t every_access = streamer_read_uhwi (ib);
	  size_t naccesses = streamer_read_uhwi (ib);

	  if (nolto_ref_node && every_access)
	    nolto_ref_node->collapse ();
	  if (lto_ref_node && every_access)
	    lto_ref_node->collapse ();

	  for (size_t k = 0; k < naccesses; k++)
	    {
	      modref_access_node a = modref_access_node::stream_in (ib);
	      if (nolto_ref_node)
		nolto_ref_node->insert_access (a, max_accesses, false);
	      if (lto_ref_node)
		lto_ref_node->insert_access (a, max_accesses, false);
	    }
	}
    }
  if (lto_ret)
    (*lto_ret)->cleanup ();
  if (nolto_ret)
    (*nolto_ret)->cleanup ();
}

/* Write ESUM to BP.  */

static void
modref_write_escape_summary (struct bitpack_d *bp, escape_summary *esum)
{
  if (!esum)
    {
      bp_pack_var_len_unsigned (bp, 0);
      return;
    }
  bp_pack_var_len_unsigned (bp, esum->esc.length ());
  unsigned int i;
  escape_entry *ee;
  FOR_EACH_VEC_ELT (esum->esc, i, ee)
    {
      bp_pack_var_len_int (bp, ee->parm_index);
      bp_pack_var_len_unsigned (bp, ee->arg);
      bp_pack_var_len_unsigned (bp, ee->min_flags);
      bp_pack_value (bp, ee->direct, 1);
    }
}

/* Read escape summary for E from BP.  */

static void
modref_read_escape_summary (struct bitpack_d *bp, cgraph_edge *e)
{
  unsigned int n = bp_unpack_var_len_unsigned (bp);
  if (!n)
    return;
  escape_summary *esum = escape_summaries->get_create (e);
  esum->esc.reserve_exact (n);
  for (unsigned int i = 0; i < n; i++)
    {
      escape_entry ee;
      ee.parm_index = bp_unpack_var_len_int (bp);
      ee.arg = bp_unpack_var_len_unsigned (bp);
      ee.min_flags = bp_unpack_var_len_unsigned (bp);
      ee.direct = bp_unpack_value (bp, 1);
      esum->esc.quick_push (ee);
    }
}

/* Callback for write_summary.  */

static void
modref_write ()
{
  struct output_block *ob = create_output_block (LTO_section_ipa_modref);
  lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
  unsigned int count = 0;
  int i;

  if (!summaries_lto)
    {
      streamer_write_uhwi (ob, 0);
      streamer_write_char_stream (ob->main_stream, 0);
      produce_asm (ob, NULL);
      destroy_output_block (ob);
      return;
    }

  for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
    {
      symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
      cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
      modref_summary_lto *r;

      if (cnode && cnode->definition && !cnode->alias
	  && (r = summaries_lto->get (cnode))
	  && r->useful_p (flags_from_decl_or_type (cnode->decl)))
	count++;
    }
  streamer_write_uhwi (ob, count);

  for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
    {
      symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
      cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);

      if (cnode && cnode->definition && !cnode->alias)
	{
	  modref_summary_lto *r = summaries_lto->get (cnode);

	  if (!r || !r->useful_p (flags_from_decl_or_type (cnode->decl)))
	    continue;

	  streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, cnode));

	  streamer_write_uhwi (ob, r->arg_flags.length ());
	  for (unsigned int i = 0; i < r->arg_flags.length (); i++)
	    streamer_write_uhwi (ob, r->arg_flags[i]);
	  streamer_write_uhwi (ob, r->retslot_flags);
	  streamer_write_uhwi (ob, r->static_chain_flags);

	  write_modref_records (r->loads, ob);
	  write_modref_records (r->stores, ob);
	  streamer_write_uhwi (ob, r->kills.length ());
	  for (auto kill : r->kills)
	    kill.stream_out (ob);

	  struct bitpack_d bp = bitpack_create (ob->main_stream);
	  bp_pack_value (&bp, r->writes_errno, 1);
	  bp_pack_value (&bp, r->side_effects, 1);
	  bp_pack_value (&bp, r->nondeterministic, 1);
	  bp_pack_value (&bp, r->calls_interposable, 1);
	  if (!flag_wpa)
	    {
	      for (cgraph_edge *e = cnode->indirect_calls;
		   e; e = e->next_callee)
		{
		  class fnspec_summary *sum = fnspec_summaries->get (e);
		  bp_pack_value (&bp, sum != NULL, 1);
		  if (sum)
		    bp_pack_string (ob, &bp, sum->fnspec, true);
		  class escape_summary *esum = escape_summaries->get (e);
		  modref_write_escape_summary (&bp,esum);
		}
	      for (cgraph_edge *e = cnode->callees; e; e = e->next_callee)
		{
		  class fnspec_summary *sum = fnspec_summaries->get (e);
		  bp_pack_value (&bp, sum != NULL, 1);
		  if (sum)
		    bp_pack_string (ob, &bp, sum->fnspec, true);
		  class escape_summary *esum = escape_summaries->get (e);
		  modref_write_escape_summary (&bp,esum);
		}
	    }
	  streamer_write_bitpack (&bp);
	}
    }
  streamer_write_char_stream (ob->main_stream, 0);
  produce_asm (ob, NULL);
  destroy_output_block (ob);
}

static void
read_section (struct lto_file_decl_data *file_data, const char *data,
	      size_t len)
{
  const struct lto_function_header *header
    = (const struct lto_function_header *) data;
  const int cfg_offset = sizeof (struct lto_function_header);
  const int main_offset = cfg_offset + header->cfg_size;
  const int string_offset = main_offset + header->main_size;
  struct data_in *data_in;
  unsigned int i;
  unsigned int f_count;

  lto_input_block ib ((const char *) data + main_offset, header->main_size,
		      file_data->mode_table);

  data_in
    = lto_data_in_create (file_data, (const char *) data + string_offset,
			  header->string_size, vNULL);
  f_count = streamer_read_uhwi (&ib);
  for (i = 0; i < f_count; i++)
    {
      struct cgraph_node *node;
      lto_symtab_encoder_t encoder;

      unsigned int index = streamer_read_uhwi (&ib);
      encoder = file_data->symtab_node_encoder;
      node = dyn_cast <cgraph_node *> (lto_symtab_encoder_deref (encoder,
								index));

      modref_summary *modref_sum = summaries
				   ? summaries->get_create (node) : NULL;
      modref_summary_lto *modref_sum_lto = summaries_lto
					   ? summaries_lto->get_create (node)
					   : NULL;
      if (optimization_summaries)
	modref_sum = optimization_summaries->get_create (node);

      if (modref_sum)
	{
	  modref_sum->writes_errno = false;
	  modref_sum->side_effects = false;
	  modref_sum->nondeterministic = false;
	  modref_sum->calls_interposable = false;
	}
      if (modref_sum_lto)
	{
	  modref_sum_lto->writes_errno = false;
	  modref_sum_lto->side_effects = false;
	  modref_sum_lto->nondeterministic = false;
	  modref_sum_lto->calls_interposable = false;
	}

      gcc_assert (!modref_sum || (!modref_sum->loads
				  && !modref_sum->stores));
      gcc_assert (!modref_sum_lto || (!modref_sum_lto->loads
				      && !modref_sum_lto->stores));
      unsigned int args = streamer_read_uhwi (&ib);
      if (args && modref_sum)
	modref_sum->arg_flags.reserve_exact (args);
      if (args && modref_sum_lto)
	modref_sum_lto->arg_flags.reserve_exact (args);
      for (unsigned int i = 0; i < args; i++)
	{
	  eaf_flags_t flags = streamer_read_uhwi (&ib);
	  if (modref_sum)
	    modref_sum->arg_flags.quick_push (flags);
	  if (modref_sum_lto)
	    modref_sum_lto->arg_flags.quick_push (flags);
	}
      eaf_flags_t flags = streamer_read_uhwi (&ib);
      if (modref_sum)
	modref_sum->retslot_flags = flags;
      if (modref_sum_lto)
	modref_sum_lto->retslot_flags = flags;

      flags = streamer_read_uhwi (&ib);
      if (modref_sum)
	modref_sum->static_chain_flags = flags;
      if (modref_sum_lto)
	modref_sum_lto->static_chain_flags = flags;

      read_modref_records (node->decl, &ib, data_in,
			   modref_sum ? &modref_sum->loads : NULL,
			   modref_sum_lto ? &modref_sum_lto->loads : NULL);
      read_modref_records (node->decl, &ib, data_in,
			   modref_sum ? &modref_sum->stores : NULL,
			   modref_sum_lto ? &modref_sum_lto->stores : NULL);
      int j = streamer_read_uhwi (&ib);
      if (j && modref_sum)
	modref_sum->kills.reserve_exact (j);
      if (j && modref_sum_lto)
	modref_sum_lto->kills.reserve_exact (j);
      for (int k = 0; k < j; k++)
	{
	  modref_access_node a = modref_access_node::stream_in (&ib);

	  if (modref_sum)
	    modref_sum->kills.quick_push (a);
	  if (modref_sum_lto)
	    modref_sum_lto->kills.quick_push (a);
	}
      struct bitpack_d bp = streamer_read_bitpack (&ib);
      if (bp_unpack_value (&bp, 1))
	{
	  if (modref_sum)
	    modref_sum->writes_errno = true;
	  if (modref_sum_lto)
	    modref_sum_lto->writes_errno = true;
	}
      if (bp_unpack_value (&bp, 1))
	{
	  if (modref_sum)
	    modref_sum->side_effects = true;
	  if (modref_sum_lto)
	    modref_sum_lto->side_effects = true;
	}
      if (bp_unpack_value (&bp, 1))
	{
	  if (modref_sum)
	    modref_sum->nondeterministic = true;
	  if (modref_sum_lto)
	    modref_sum_lto->nondeterministic = true;
	}
      if (bp_unpack_value (&bp, 1))
	{
	  if (modref_sum)
	    modref_sum->calls_interposable = true;
	  if (modref_sum_lto)
	    modref_sum_lto->calls_interposable = true;
	}
      if (!flag_ltrans)
	{
	  for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee)
	    {
	      if (bp_unpack_value (&bp, 1))
		{
		  class fnspec_summary *sum = fnspec_summaries->get_create (e);
		  sum->fnspec = xstrdup (bp_unpack_string (data_in, &bp));
		}
	      modref_read_escape_summary (&bp, e);
	    }
	  for (cgraph_edge *e = node->callees; e; e = e->next_callee)
	    {
	      if (bp_unpack_value (&bp, 1))
		{
		  class fnspec_summary *sum = fnspec_summaries->get_create (e);
		  sum->fnspec = xstrdup (bp_unpack_string (data_in, &bp));
		}
	      modref_read_escape_summary (&bp, e);
	    }
	}
      if (flag_ltrans)
	modref_sum->finalize (node->decl);
      if (dump_file)
	{
	  fprintf (dump_file, "Read modref for %s\n",
		   node->dump_name ());
	  if (modref_sum)
	    modref_sum->dump (dump_file);
	  if (modref_sum_lto)
	    modref_sum_lto->dump (dump_file);
	  dump_modref_edge_summaries (dump_file, node, 4);
	}
    }

  lto_free_section_data (file_data, LTO_section_ipa_modref, NULL, data,
			 len);
  lto_data_in_delete (data_in);
}

/* Callback for read_summary.  */

static void
modref_read (void)
{
  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
  struct lto_file_decl_data *file_data;
  unsigned int j = 0;

  gcc_checking_assert (!optimization_summaries && !summaries && !summaries_lto);
  if (flag_ltrans)
    optimization_summaries = modref_summaries::create_ggc (symtab);
  else
    {
      if (flag_wpa || flag_incremental_link == INCREMENTAL_LINK_LTO)
	summaries_lto = modref_summaries_lto::create_ggc (symtab);
      if (!flag_wpa
	  || (flag_incremental_link == INCREMENTAL_LINK_LTO
	      && flag_fat_lto_objects))
	summaries = modref_summaries::create_ggc (symtab);
      if (!fnspec_summaries)
	fnspec_summaries = new fnspec_summaries_t (symtab);
      if (!escape_summaries)
	escape_summaries = new escape_summaries_t (symtab);
    }

  while ((file_data = file_data_vec[j++]))
    {
      size_t len;
      const char *data = lto_get_summary_section_data (file_data,
						       LTO_section_ipa_modref,
						       &len);
      if (data)
	read_section (file_data, data, len);
      else
	/* Fatal error here.  We do not want to support compiling ltrans units
	   with different version of compiler or different flags than the WPA
	   unit, so this should never happen.  */
	fatal_error (input_location,
		     "IPA modref summary is missing in input file");
    }
}

/* Recompute arg_flags for param adjustments in INFO.  */

static void
remap_arg_flags (auto_vec <eaf_flags_t> &arg_flags, clone_info *info)
{
  auto_vec<eaf_flags_t> old = arg_flags.copy ();
  int max = -1;
  size_t i;
  ipa_adjusted_param *p;

  arg_flags.release ();

  FOR_EACH_VEC_SAFE_ELT (info->param_adjustments->m_adj_params, i, p)
    {
      int o = info->param_adjustments->get_original_index (i);
      if (o >= 0 && (int)old.length () > o && old[o])
	max = i;
    }
  if (max >= 0)
    arg_flags.safe_grow_cleared (max + 1, true);
  FOR_EACH_VEC_SAFE_ELT (info->param_adjustments->m_adj_params, i, p)
    {
      int o = info->param_adjustments->get_original_index (i);
      if (o >= 0 && (int)old.length () > o && old[o])
	arg_flags[i] = old[o];
    }
}

/* Update kills accrdoing to the parm map MAP.  */

static void
remap_kills (vec <modref_access_node> &kills, const vec <int> &map)
{
  for (size_t i = 0; i < kills.length ();)
    if (kills[i].parm_index >= 0)
      {
	if (kills[i].parm_index < (int)map.length ()
	    && map[kills[i].parm_index] != MODREF_UNKNOWN_PARM)
	  {
	    kills[i].parm_index = map[kills[i].parm_index];
	    i++;
	  }
	else
	  kills.unordered_remove (i);
      }
    else
      i++;
}

/* If signature changed, update the summary.  */

static void
update_signature (struct cgraph_node *node)
{
  clone_info *info = clone_info::get (node);
  if (!info || !info->param_adjustments)
    return;

  modref_summary *r = optimization_summaries
		      ? optimization_summaries->get (node) : NULL;
  modref_summary_lto *r_lto = summaries_lto
			      ? summaries_lto->get (node) : NULL;
  if (!r && !r_lto)
    return;
  if (dump_file)
    {
      fprintf (dump_file, "Updating summary for %s from:\n",
	       node->dump_name ());
      if (r)
	r->dump (dump_file);
      if (r_lto)
	r_lto->dump (dump_file);
    }

  size_t i, max = 0;
  ipa_adjusted_param *p;

  FOR_EACH_VEC_SAFE_ELT (info->param_adjustments->m_adj_params, i, p)
    {
      int idx = info->param_adjustments->get_original_index (i);
      if (idx > (int)max)
	max = idx;
    }

  auto_vec <int, 32> map;

  map.reserve (max + 1);
  for (i = 0; i <= max; i++)
    map.quick_push (MODREF_UNKNOWN_PARM);
  FOR_EACH_VEC_SAFE_ELT (info->param_adjustments->m_adj_params, i, p)
    {
      int idx = info->param_adjustments->get_original_index (i);
      if (idx >= 0)
	map[idx] = i;
    }
  if (r)
    {
      r->loads->remap_params (&map);
      r->stores->remap_params (&map);
      remap_kills (r->kills, map);
      if (r->arg_flags.length ())
	remap_arg_flags (r->arg_flags, info);
    }
  if (r_lto)
    {
      r_lto->loads->remap_params (&map);
      r_lto->stores->remap_params (&map);
      remap_kills (r_lto->kills, map);
      if (r_lto->arg_flags.length ())
	remap_arg_flags (r_lto->arg_flags, info);
    }
  if (dump_file)
    {
      fprintf (dump_file, "to:\n");
      if (r)
	r->dump (dump_file);
      if (r_lto)
	r_lto->dump (dump_file);
    }
  if (r)
    r->finalize (node->decl);
  return;
}

/* Definition of the modref IPA pass.  */
const pass_data pass_data_ipa_modref =
{
  IPA_PASS,           /* type */
  "modref",       /* name */
  OPTGROUP_IPA,       /* optinfo_flags */
  TV_IPA_MODREF, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  ( TODO_dump_symtab ), /* todo_flags_finish */
};

class pass_ipa_modref : public ipa_opt_pass_d
{
public:
  pass_ipa_modref (gcc::context *ctxt)
    : ipa_opt_pass_d (pass_data_ipa_modref, ctxt,
		      modref_generate, /* generate_summary */
		      modref_write,    /* write_summary */
		      modref_read,     /* read_summary */
		      modref_write,    /* write_optimization_summary */
		      modref_read,     /* read_optimization_summary */
		      NULL,            /* stmt_fixup */
		      0,               /* function_transform_todo_flags_start */
		      NULL,	       /* function_transform */
		      NULL)            /* variable_transform */
  {}

  /* opt_pass methods: */
  opt_pass *clone () { return new pass_ipa_modref (m_ctxt); }
  virtual bool gate (function *)
  {
    return true;
  }
  virtual unsigned int execute (function *);

};

}

unsigned int pass_modref::execute (function *)
{
  if (analyze_function (false))
    return execute_fixup_cfg ();
  return 0;
}

gimple_opt_pass *
make_pass_modref (gcc::context *ctxt)
{
  return new pass_modref (ctxt);
}

ipa_opt_pass_d *
make_pass_ipa_modref (gcc::context *ctxt)
{
  return new pass_ipa_modref (ctxt);
}

namespace {

/* Skip edges from and to nodes without ipa_pure_const enabled.
   Ignore not available symbols.  */

static bool
ignore_edge (struct cgraph_edge *e)
{
  /* We merge summaries of inline clones into summaries of functions they
     are inlined to.  For that reason the complete function bodies must
     act as unit.  */
  if (!e->inline_failed)
    return false;
  enum availability avail;
  cgraph_node *callee = e->callee->ultimate_alias_target
			  (&avail, e->caller);

  return (avail <= AVAIL_INTERPOSABLE
	  || ((!optimization_summaries || !optimization_summaries->get (callee))
	      && (!summaries_lto || !summaries_lto->get (callee))));
}

/* Compute parm_map for CALLEE_EDGE.  */

static bool
compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
{
  class ipa_edge_args *args;
  if (ipa_node_params_sum
      && !callee_edge->call_stmt_cannot_inline_p
      && (args = ipa_edge_args_sum->get (callee_edge)) != NULL)
    {
      int i, count = ipa_get_cs_argument_count (args);
      class ipa_node_params *caller_parms_info, *callee_pi;
      class ipa_call_summary *es
	     = ipa_call_summaries->get (callee_edge);
      cgraph_node *callee
	 = callee_edge->callee->ultimate_alias_target
			      (NULL, callee_edge->caller);

      caller_parms_info
	= ipa_node_params_sum->get (callee_edge->caller->inlined_to
				    ? callee_edge->caller->inlined_to
				    : callee_edge->caller);
      callee_pi = ipa_node_params_sum->get (callee);

      (*parm_map).safe_grow_cleared (count, true);

      for (i = 0; i < count; i++)
	{
	  if (es && es->param[i].points_to_local_or_readonly_memory)
	    {
	      (*parm_map)[i].parm_index = MODREF_LOCAL_MEMORY_PARM;
	      continue;
	    }

	  struct ipa_jump_func *jf
	     = ipa_get_ith_jump_func (args, i);
	  if (jf && callee_pi)
	    {
	      tree cst = ipa_value_from_jfunc (caller_parms_info,
					       jf,
					       ipa_get_type
						 (callee_pi, i));
	      if (cst && points_to_local_or_readonly_memory_p (cst))
		{
		  (*parm_map)[i].parm_index = MODREF_LOCAL_MEMORY_PARM;
		  continue;
		}
	    }
	  if (jf && jf->type == IPA_JF_PASS_THROUGH)
	    {
	      (*parm_map)[i].parm_index
		= ipa_get_jf_pass_through_formal_id (jf);
	      if (ipa_get_jf_pass_through_operation (jf) == NOP_EXPR)
		{
		  (*parm_map)[i].parm_offset_known = true;
		  (*parm_map)[i].parm_offset = 0;
		}
	      else if (ipa_get_jf_pass_through_operation (jf)
		       == POINTER_PLUS_EXPR
		       && ptrdiff_tree_p (ipa_get_jf_pass_through_operand (jf),
					  &(*parm_map)[i].parm_offset))
		(*parm_map)[i].parm_offset_known = true;
	      else
		(*parm_map)[i].parm_offset_known = false;
	      continue;
	    }
	  if (jf && jf->type == IPA_JF_ANCESTOR)
	    {
	      (*parm_map)[i].parm_index = ipa_get_jf_ancestor_formal_id (jf);
	      (*parm_map)[i].parm_offset_known = true;
	      gcc_checking_assert
		(!(ipa_get_jf_ancestor_offset (jf) & (BITS_PER_UNIT - 1)));
	      (*parm_map)[i].parm_offset
		 = ipa_get_jf_ancestor_offset (jf) >> LOG2_BITS_PER_UNIT;
	    }
	  else
	    (*parm_map)[i].parm_index = -1;
	}
      if (dump_file)
	{
	  fprintf (dump_file, "  Parm map: ");
	  for (i = 0; i < count; i++)
	    fprintf (dump_file, " %i", (*parm_map)[i].parm_index);
	  fprintf (dump_file, "\n");
	}
      return true;
    }
  return false;
}

/* Map used to translate escape infos.  */

struct escape_map
{
  int parm_index;
  bool direct;
};

/* Update escape map for E.  */

static void
update_escape_summary_1 (cgraph_edge *e,
			 vec <vec <escape_map>> &map,
			 bool ignore_stores)
{
  escape_summary *sum = escape_summaries->get (e);
  if (!sum)
    return;
  auto_vec <escape_entry> old = sum->esc.copy ();
  sum->esc.release ();

  unsigned int i;
  escape_entry *ee;
  FOR_EACH_VEC_ELT (old, i, ee)
    {
      unsigned int j;
      struct escape_map *em;
      /* TODO: We do not have jump functions for return slots, so we
	 never propagate them to outer function.  */
      if (ee->parm_index >= (int)map.length ()
	  || ee->parm_index < 0)
	continue;
      FOR_EACH_VEC_ELT (map[ee->parm_index], j, em)
	{
	  int min_flags = ee->min_flags;
	  if (ee->direct && !em->direct)
	    min_flags = deref_flags (min_flags, ignore_stores);
	  struct escape_entry entry = {em->parm_index, ee->arg,
				       min_flags,
				       ee->direct & em->direct};
	  sum->esc.safe_push (entry);
	}
    }
  if (!sum->esc.length ())
    escape_summaries->remove (e);
}

/* Update escape map fo NODE.  */

static void
update_escape_summary (cgraph_node *node,
		       vec <vec <escape_map>> &map,
		       bool ignore_stores)
{
  if (!escape_summaries)
    return;
  for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee)
    update_escape_summary_1 (e, map, ignore_stores);
  for (cgraph_edge *e = node->callees; e; e = e->next_callee)
    {
      if (!e->inline_failed)
	update_escape_summary (e->callee, map, ignore_stores);
      else
	update_escape_summary_1 (e, map, ignore_stores);
    }
}

/* Get parameter type from DECL.  This is only safe for special cases
   like builtins we create fnspec for because the type match is checked
   at fnspec creation time.  */

static tree
get_parm_type (tree decl, unsigned int i)
{
  tree t = TYPE_ARG_TYPES (TREE_TYPE (decl));

  for (unsigned int p = 0; p < i; p++)
    t = TREE_CHAIN (t);
  return TREE_VALUE (t);
}

/* Return access mode for argument I of call E with FNSPEC.  */

static modref_access_node
get_access_for_fnspec (cgraph_edge *e, attr_fnspec &fnspec,
		       unsigned int i, modref_parm_map &map)
{
  tree size = NULL_TREE;
  unsigned int size_arg;

  if (!fnspec.arg_specified_p (i))
    ;
  else if (fnspec.arg_max_access_size_given_by_arg_p (i, &size_arg))
    {
      cgraph_node *node = e->caller->inlined_to
			  ? e->caller->inlined_to : e->caller;
      ipa_node_params *caller_parms_info = ipa_node_params_sum->get (node);
      ipa_edge_args *args = ipa_edge_args_sum->get (e);
      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, size_arg);

      if (jf)
	size = ipa_value_from_jfunc (caller_parms_info, jf,
				     get_parm_type (e->callee->decl, size_arg));
    }
  else if (fnspec.arg_access_size_given_by_type_p (i))
    size = TYPE_SIZE_UNIT (get_parm_type (e->callee->decl, i));
  modref_access_node a = {0, -1, -1,
			  map.parm_offset, map.parm_index,
			  map.parm_offset_known, 0};
  poly_int64 size_hwi;
  if (size
      && poly_int_tree_p (size, &size_hwi)
      && coeffs_in_range_p (size_hwi, 0,
			    HOST_WIDE_INT_MAX / BITS_PER_UNIT))
    {
      a.size = -1;
      a.max_size = size_hwi << LOG2_BITS_PER_UNIT;
    }
  return a;
}

 /* Collapse loads and return true if something changed.  */
static bool
collapse_loads (modref_summary *cur_summary,
		modref_summary_lto *cur_summary_lto)
{
  bool changed = false;

  if (cur_summary && !cur_summary->loads->every_base)
    {
      cur_summary->loads->collapse ();
      changed = true;
    }
  if (cur_summary_lto
      && !cur_summary_lto->loads->every_base)
    {
      cur_summary_lto->loads->collapse ();
      changed = true;
    }
  return changed;
}

/* Collapse loads and return true if something changed.  */

static bool
collapse_stores (modref_summary *cur_summary,
		modref_summary_lto *cur_summary_lto)
{
  bool changed = false;

  if (cur_summary && !cur_summary->stores->every_base)
    {
      cur_summary->stores->collapse ();
      changed = true;
    }
  if (cur_summary_lto
      && !cur_summary_lto->stores->every_base)
    {
      cur_summary_lto->stores->collapse ();
      changed = true;
    }
  return changed;
}

/* Call E in NODE with ECF_FLAGS has no summary; update MODREF_SUMMARY and
   CUR_SUMMARY_LTO accordingly.  Return true if something changed.  */

static bool
propagate_unknown_call (cgraph_node *node,
			cgraph_edge *e, int ecf_flags,
			modref_summary *cur_summary,
			modref_summary_lto *cur_summary_lto,
			bool nontrivial_scc)
{
  bool changed = false;
  class fnspec_summary *fnspec_sum = fnspec_summaries->get (e);
  auto_vec <modref_parm_map, 32> parm_map;
  bool looping;

  if (e->callee
      && builtin_safe_for_const_function_p (&looping, e->callee->decl))
    {
      if (looping && cur_summary && !cur_summary->side_effects)
	{
	  cur_summary->side_effects = true;
	  changed = true;
	}
      if (looping && cur_summary_lto && !cur_summary_lto->side_effects)
	{
	  cur_summary_lto->side_effects = true;
	  changed = true;
	}
      return changed;
    }

  if (!(ecf_flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE))
      || (ecf_flags & ECF_LOOPING_CONST_OR_PURE)
      || nontrivial_scc)
    {
      if (cur_summary && !cur_summary->side_effects)
	{
	  cur_summary->side_effects = true;
	  changed = true;
	}
      if (cur_summary_lto && !cur_summary_lto->side_effects)
	{
	  cur_summary_lto->side_effects = true;
	  changed = true;
	}
      if (cur_summary && !cur_summary->nondeterministic
	  && !ignore_nondeterminism_p (node->decl, ecf_flags))
	{
	  cur_summary->nondeterministic = true;
	  changed = true;
	}
      if (cur_summary_lto && !cur_summary_lto->nondeterministic
	  && !ignore_nondeterminism_p (node->decl, ecf_flags))
	{
	  cur_summary_lto->nondeterministic = true;
	  changed = true;
	}
    }
  if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
    return changed;

  if (fnspec_sum
      && compute_parm_map (e, &parm_map))
    {
      attr_fnspec fnspec (fnspec_sum->fnspec);

      gcc_checking_assert (fnspec.known_p ());
      if (fnspec.global_memory_read_p ())
	collapse_loads (cur_summary, cur_summary_lto);
      else
	{
	  tree t = TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl));
	  for (unsigned i = 0; i < parm_map.length () && t;
	       i++, t = TREE_CHAIN (t))
	    if (!POINTER_TYPE_P (TREE_VALUE (t)))
	      ;
	  else if (!fnspec.arg_specified_p (i)
		   || fnspec.arg_maybe_read_p (i))
	    {
	      modref_parm_map map = parm_map[i];
	      if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
		continue;
	      if (map.parm_index == MODREF_UNKNOWN_PARM)
		{
		  collapse_loads (cur_summary, cur_summary_lto);
		  break;
		}
	      if (cur_summary)
		changed |= cur_summary->loads->insert
		  (node->decl, 0, 0,
		   get_access_for_fnspec (e, fnspec, i, map), false);
	      if (cur_summary_lto)
		changed |= cur_summary_lto->loads->insert
		  (node->decl, 0, 0,
		   get_access_for_fnspec (e, fnspec, i, map), false);
	    }
	}
      if (ignore_stores_p (node->decl, ecf_flags))
	;
      else if (fnspec.global_memory_written_p ())
	collapse_stores (cur_summary, cur_summary_lto);
      else
	{
	  tree t = TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl));
	  for (unsigned i = 0; i < parm_map.length () && t;
	       i++, t = TREE_CHAIN (t))
	    if (!POINTER_TYPE_P (TREE_VALUE (t)))
	      ;
	  else if (!fnspec.arg_specified_p (i)
		   || fnspec.arg_maybe_written_p (i))
	    {
	      modref_parm_map map = parm_map[i];
	      if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
		continue;
	      if (map.parm_index == MODREF_UNKNOWN_PARM)
		{
		  collapse_stores (cur_summary, cur_summary_lto);
		  break;
		}
	      if (cur_summary)
		changed |= cur_summary->stores->insert
		  (node->decl, 0, 0,
		   get_access_for_fnspec (e, fnspec, i, map), false);
	      if (cur_summary_lto)
		changed |= cur_summary_lto->stores->insert
		  (node->decl, 0, 0,
		   get_access_for_fnspec (e, fnspec, i, map), false);
	    }
	}
      if (fnspec.errno_maybe_written_p () && flag_errno_math)
	{
	  if (cur_summary && !cur_summary->writes_errno)
	    {
	      cur_summary->writes_errno = true;
	      changed = true;
	    }
	  if (cur_summary_lto && !cur_summary_lto->writes_errno)
	    {
	      cur_summary_lto->writes_errno = true;
	      changed = true;
	    }
	}
      return changed;
    }
  if (dump_file)
    fprintf (dump_file, "      collapsing loads\n");
  changed |= collapse_loads (cur_summary, cur_summary_lto);
  if (!ignore_stores_p (node->decl, ecf_flags))
    {
      if (dump_file)
	fprintf (dump_file, "      collapsing stores\n");
      changed |= collapse_stores (cur_summary, cur_summary_lto);
    }
  return changed;
}

/* Maybe remove summaies of NODE pointed to by CUR_SUMMARY_PTR
   and CUR_SUMMARY_LTO_PTR if they are useless according to ECF_FLAGS.  */

static void
remove_useless_summaries (cgraph_node *node,
			  modref_summary **cur_summary_ptr,
			  modref_summary_lto **cur_summary_lto_ptr,
			  int ecf_flags)
{
  if (*cur_summary_ptr && !(*cur_summary_ptr)->useful_p (ecf_flags, false))
    {
      optimization_summaries->remove (node);
      *cur_summary_ptr = NULL;
    }
  if (*cur_summary_lto_ptr
      && !(*cur_summary_lto_ptr)->useful_p (ecf_flags, false))
    {
      summaries_lto->remove (node);
      *cur_summary_lto_ptr = NULL;
    }
}

/* Perform iterative dataflow on SCC component starting in COMPONENT_NODE
   and propagate loads/stores.  */

static bool
modref_propagate_in_scc (cgraph_node *component_node)
{
  bool changed = true;
  bool first = true;
  int iteration = 0;

  while (changed)
    {
      bool nontrivial_scc
		 = ((struct ipa_dfs_info *) component_node->aux)->next_cycle;
      changed = false;
      for (struct cgraph_node *cur = component_node; cur;
	   cur = ((struct ipa_dfs_info *) cur->aux)->next_cycle)
	{
	  cgraph_node *node = cur->inlined_to ? cur->inlined_to : cur;
	  modref_summary *cur_summary = optimization_summaries
					? optimization_summaries->get (node)
					: NULL;
	  modref_summary_lto *cur_summary_lto = summaries_lto
						? summaries_lto->get (node)
						: NULL;

	  if (!cur_summary && !cur_summary_lto)
	    continue;

	  int cur_ecf_flags = flags_from_decl_or_type (node->decl);

	  if (dump_file)
	    fprintf (dump_file, "  Processing %s%s%s\n",
		     cur->dump_name (),
		     TREE_READONLY (cur->decl) ? " (const)" : "",
		     DECL_PURE_P (cur->decl) ? " (pure)" : "");

	  for (cgraph_edge *e = cur->indirect_calls; e; e = e->next_callee)
	    {
	      if (dump_file)
		fprintf (dump_file, "    Indirect call\n");
	      if (propagate_unknown_call
			   (node, e, e->indirect_info->ecf_flags,
			    cur_summary, cur_summary_lto,
			    nontrivial_scc))
		{
		  changed = true;
		  remove_useless_summaries (node, &cur_summary,
					    &cur_summary_lto,
					    cur_ecf_flags);
		  if (!cur_summary && !cur_summary_lto)
		    break;
		}
	    }

	  if (!cur_summary && !cur_summary_lto)
	    continue;

	  for (cgraph_edge *callee_edge = cur->callees; callee_edge;
	       callee_edge = callee_edge->next_callee)
	    {
	      int flags = flags_from_decl_or_type (callee_edge->callee->decl);
	      modref_summary *callee_summary = NULL;
	      modref_summary_lto *callee_summary_lto = NULL;
	      struct cgraph_node *callee;

	      if (!callee_edge->inline_failed
		 || ((flags & (ECF_CONST | ECF_NOVOPS))
		     && !(flags & ECF_LOOPING_CONST_OR_PURE)))
		continue;

	      /* Get the callee and its summary.  */
	      enum availability avail;
	      callee = callee_edge->callee->ultimate_alias_target
			 (&avail, cur);

	      /* It is not necessary to re-process calls outside of the
		 SCC component.  */
	      if (iteration > 0
		  && (!callee->aux
		      || ((struct ipa_dfs_info *)cur->aux)->scc_no
			  != ((struct ipa_dfs_info *)callee->aux)->scc_no))
		continue;

	      if (dump_file)
		fprintf (dump_file, "    Call to %s\n",
			 callee_edge->callee->dump_name ());

	      bool ignore_stores = ignore_stores_p (cur->decl, flags);

	      if (avail <= AVAIL_INTERPOSABLE)
		{
		  if (dump_file)
		    fprintf (dump_file, "      Call target interposable"
			     " or not available\n");
		  changed |= propagate_unknown_call
			       (node, callee_edge, flags,
				cur_summary, cur_summary_lto,
				nontrivial_scc);
		  if (!cur_summary && !cur_summary_lto)
		    break;
		  continue;
		}

	      /* We don't know anything about CALLEE, hence we cannot tell
		 anything about the entire component.  */

	      if (cur_summary
		  && !(callee_summary = optimization_summaries->get (callee)))
		{
		  if (dump_file)
		    fprintf (dump_file, "      No call target summary\n");
		  changed |= propagate_unknown_call
			       (node, callee_edge, flags,
				cur_summary, NULL,
				nontrivial_scc);
		}
	      if (cur_summary_lto
		  && !(callee_summary_lto = summaries_lto->get (callee)))
		{
		  if (dump_file)
		    fprintf (dump_file, "      No call target summary\n");
		  changed |= propagate_unknown_call
			       (node, callee_edge, flags,
				NULL, cur_summary_lto,
				nontrivial_scc);
		}

	      if (callee_summary && !cur_summary->side_effects
		  && (callee_summary->side_effects
		      || callee_edge->recursive_p ()))
		{
		  cur_summary->side_effects = true;
		  changed = true;
		}
	      if (callee_summary_lto && !cur_summary_lto->side_effects
		  && (callee_summary_lto->side_effects
		      || callee_edge->recursive_p ()))
		{
		  cur_summary_lto->side_effects = true;
		  changed = true;
		}
	      if (callee_summary && !cur_summary->nondeterministic
		  && callee_summary->nondeterministic
		  && !ignore_nondeterminism_p (cur->decl, flags))
		{
		  cur_summary->nondeterministic = true;
		  changed = true;
		}
	      if (callee_summary_lto && !cur_summary_lto->nondeterministic
		  && callee_summary_lto->nondeterministic
		  && !ignore_nondeterminism_p (cur->decl, flags))
		{
		  cur_summary_lto->nondeterministic = true;
		  changed = true;
		}
	      if (flags & (ECF_CONST | ECF_NOVOPS))
		continue;

	      /* We can not safely optimize based on summary of callee if it
		 does not always bind to current def: it is possible that
		 memory load was optimized out earlier which may not happen in
		 the interposed variant.  */
	      if (!callee_edge->binds_to_current_def_p ())
		{
		  if (cur_summary && !cur_summary->calls_interposable)
		    {
		      cur_summary->calls_interposable = true;
		      changed = true;
		    }
		  if (cur_summary_lto && !cur_summary_lto->calls_interposable)
		    {
		      cur_summary_lto->calls_interposable = true;
		      changed = true;
		    }
		  if (dump_file)
		    fprintf (dump_file, "      May not bind local;"
			     " collapsing loads\n");
		}


	      auto_vec <modref_parm_map, 32> parm_map;
	      modref_parm_map chain_map;
	      /* TODO: Once we get jump functions for static chains we could
		 compute this.  */
	      chain_map.parm_index = MODREF_UNKNOWN_PARM;

	      compute_parm_map (callee_edge, &parm_map);

	      /* Merge in callee's information.  */
	      if (callee_summary)
		{
		  changed |= cur_summary->loads->merge
				  (node->decl, callee_summary->loads,
				   &parm_map, &chain_map, !first);
		  if (!ignore_stores)
		    {
		      changed |= cur_summary->stores->merge
				      (node->decl, callee_summary->stores,
				       &parm_map, &chain_map, !first);
		      if (!cur_summary->writes_errno
			  && callee_summary->writes_errno)
			{
			  cur_summary->writes_errno = true;
			  changed = true;
			}
		    }
		}
	      if (callee_summary_lto)
		{
		  changed |= cur_summary_lto->loads->merge
				  (node->decl, callee_summary_lto->loads,
				   &parm_map, &chain_map, !first);
		  if (!ignore_stores)
		    {
		      changed |= cur_summary_lto->stores->merge
				      (node->decl, callee_summary_lto->stores,
				       &parm_map, &chain_map, !first);
		      if (!cur_summary_lto->writes_errno
			  && callee_summary_lto->writes_errno)
			{
			  cur_summary_lto->writes_errno = true;
			  changed = true;
			}
		    }
		}
	      if (changed)
		remove_useless_summaries (node, &cur_summary,
					  &cur_summary_lto,
					  cur_ecf_flags);
	      if (!cur_summary && !cur_summary_lto)
		break;
	      if (dump_file && changed)
		{
		  if (cur_summary)
		    cur_summary->dump (dump_file);
		  if (cur_summary_lto)
		    cur_summary_lto->dump (dump_file);
		  dump_modref_edge_summaries (dump_file, node, 4);
		}
	    }
	}
      iteration++;
      first = false;
    }
  if (dump_file)
    fprintf (dump_file,
	     "Propagation finished in %i iterations\n", iteration);
  bool pureconst = false;
  for (struct cgraph_node *cur = component_node; cur;
       cur = ((struct ipa_dfs_info *) cur->aux)->next_cycle)
    if (!cur->inlined_to && opt_for_fn (cur->decl, flag_ipa_pure_const))
      {
	modref_summary *summary = optimization_summaries
				  ? optimization_summaries->get (cur)
				  : NULL;
	modref_summary_lto *summary_lto = summaries_lto
					  ? summaries_lto->get (cur)
					  : NULL;
	if (summary && !summary->stores->every_base && !summary->stores->bases
	    && !summary->nondeterministic)
	  {
	    if (!summary->loads->every_base && !summary->loads->bases
		&& !summary->calls_interposable)
	      pureconst |= ipa_make_function_const
		     (cur, summary->side_effects, false);
	    else
	      pureconst |= ipa_make_function_pure
		     (cur, summary->side_effects, false);
	  }
	if (summary_lto && !summary_lto->stores->every_base
	    && !summary_lto->stores->bases && !summary_lto->nondeterministic)
	  {
	    if (!summary_lto->loads->every_base && !summary_lto->loads->bases
		&& !summary_lto->calls_interposable)
	      pureconst |= ipa_make_function_const
		     (cur, summary_lto->side_effects, false);
	    else
	      pureconst |= ipa_make_function_pure
		     (cur, summary_lto->side_effects, false);
	  }
     }
  return pureconst;
}

/* Dump results of propagation in SCC rooted in COMPONENT_NODE.  */

static void
modref_propagate_dump_scc (cgraph_node *component_node)
{
  for (struct cgraph_node *cur = component_node; cur;
       cur = ((struct ipa_dfs_info *) cur->aux)->next_cycle)
    if (!cur->inlined_to)
      {
	modref_summary *cur_summary = optimization_summaries
				      ? optimization_summaries->get (cur)
				      : NULL;
	modref_summary_lto *cur_summary_lto = summaries_lto
					      ? summaries_lto->get (cur)
					      : NULL;

	fprintf (dump_file, "Propagated modref for %s%s%s\n",
		 cur->dump_name (),
		 TREE_READONLY (cur->decl) ? " (const)" : "",
		 DECL_PURE_P (cur->decl) ? " (pure)" : "");
	if (optimization_summaries)
	  {
	    if (cur_summary)
	      cur_summary->dump (dump_file);
	    else
	      fprintf (dump_file, "  Not tracked\n");
	  }
	if (summaries_lto)
	  {
	    if (cur_summary_lto)
	      cur_summary_lto->dump (dump_file);
	    else
	      fprintf (dump_file, "  Not tracked (lto)\n");
	  }
      }
}

/* Determine EAF flags know for call E with CALLEE_ECF_FLAGS and ARG.  */

int
implicit_eaf_flags_for_edge_and_arg (cgraph_edge *e, int callee_ecf_flags,
				     bool ignore_stores, int arg)
{
  /* Returning the value is already accounted to at local propagation.  */
  int implicit_flags = EAF_NOT_RETURNED_DIRECTLY
		       | EAF_NOT_RETURNED_INDIRECTLY;
  if (ignore_stores)
     implicit_flags |= ignore_stores_eaf_flags;
  if (callee_ecf_flags & ECF_PURE)
    implicit_flags |= implicit_pure_eaf_flags;
  if (callee_ecf_flags & (ECF_CONST | ECF_NOVOPS))
    implicit_flags |= implicit_const_eaf_flags;
  class fnspec_summary *fnspec_sum = fnspec_summaries->get (e);
  if (fnspec_sum)
    {
      attr_fnspec fnspec (fnspec_sum->fnspec);
      implicit_flags |= fnspec.arg_eaf_flags (arg);
    }
  return implicit_flags;
}

/* Process escapes in SUM and merge SUMMARY to CUR_SUMMARY
   and SUMMARY_LTO to CUR_SUMMARY_LTO.
   Return true if something changed.  */

static bool
modref_merge_call_site_flags (escape_summary *sum,
			      modref_summary *cur_summary,
			      modref_summary_lto *cur_summary_lto,
			      modref_summary *summary,
			      modref_summary_lto *summary_lto,
			      tree caller,
			      cgraph_edge *e,
			      int caller_ecf_flags,
			      int callee_ecf_flags,
			      bool binds_to_current_def)
{
  escape_entry *ee;
  unsigned int i;
  bool changed = false;
  bool ignore_stores = ignore_stores_p (caller, callee_ecf_flags);

  /* Return early if we have no useful info to propagate.  */
  if ((!cur_summary
       || (!cur_summary->arg_flags.length ()
	   && !cur_summary->static_chain_flags
	   && !cur_summary->retslot_flags))
      && (!cur_summary_lto
	  || (!cur_summary_lto->arg_flags.length ()
	      && !cur_summary_lto->static_chain_flags
	      && !cur_summary_lto->retslot_flags)))
    return false;

  FOR_EACH_VEC_ELT (sum->esc, i, ee)
    {
      int flags = 0;
      int flags_lto = 0;
      int implicit_flags = implicit_eaf_flags_for_edge_and_arg
				(e, callee_ecf_flags, ignore_stores, ee->arg);

      if (summary && ee->arg < summary->arg_flags.length ())
	flags = summary->arg_flags[ee->arg];
      if (summary_lto
	  && ee->arg < summary_lto->arg_flags.length ())
	flags_lto = summary_lto->arg_flags[ee->arg];
      if (!ee->direct)
	{
	  flags = deref_flags (flags, ignore_stores);
	  flags_lto = deref_flags (flags_lto, ignore_stores);
	}
      if (ignore_stores)
	 implicit_flags |= ignore_stores_eaf_flags;
      if (callee_ecf_flags & ECF_PURE)
	implicit_flags |= implicit_pure_eaf_flags;
      if (callee_ecf_flags & (ECF_CONST | ECF_NOVOPS))
	implicit_flags |= implicit_const_eaf_flags;
      class fnspec_summary *fnspec_sum = fnspec_summaries->get (e);
      if (fnspec_sum)
	{
	  attr_fnspec fnspec (fnspec_sum->fnspec);
	  implicit_flags |= fnspec.arg_eaf_flags (ee->arg);
	}
      if (!ee->direct)
	implicit_flags = deref_flags (implicit_flags, ignore_stores);
      flags |= implicit_flags;
      flags_lto |= implicit_flags;
      if (!binds_to_current_def && (flags || flags_lto))
	{
	  flags = interposable_eaf_flags (flags, implicit_flags);
	  flags_lto = interposable_eaf_flags (flags_lto, implicit_flags);
	}
      if (!(flags & EAF_UNUSED)
	  && cur_summary && ee->parm_index < (int)cur_summary->arg_flags.length ())
	{
	  eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM
			   ? cur_summary->retslot_flags
			   : ee->parm_index == MODREF_STATIC_CHAIN_PARM
			   ? cur_summary->static_chain_flags
			   : cur_summary->arg_flags[ee->parm_index];
	  if ((f & flags) != f)
	    {
	      f = remove_useless_eaf_flags
			 (f & flags, caller_ecf_flags,
			  VOID_TYPE_P (TREE_TYPE (TREE_TYPE (caller))));
	      changed = true;
	    }
	}
      if (!(flags_lto & EAF_UNUSED)
	  && cur_summary_lto
	  && ee->parm_index < (int)cur_summary_lto->arg_flags.length ())
	{
	  eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM
			   ? cur_summary_lto->retslot_flags
			   : ee->parm_index == MODREF_STATIC_CHAIN_PARM
			   ? cur_summary_lto->static_chain_flags
			   : cur_summary_lto->arg_flags[ee->parm_index];
	  if ((f & flags_lto) != f)
	    {
	      f = remove_useless_eaf_flags
			 (f & flags_lto, caller_ecf_flags,
			  VOID_TYPE_P (TREE_TYPE (TREE_TYPE (caller))));
	      changed = true;
	    }
	}
    }
  return changed;
}

/* Perform iterative dataflow on SCC component starting in COMPONENT_NODE
   and propagate arg flags.  */

static void
modref_propagate_flags_in_scc (cgraph_node *component_node)
{
  bool changed = true;
  int iteration = 0;

  while (changed)
    {
      changed = false;
      for (struct cgraph_node *cur = component_node; cur;
	   cur = ((struct ipa_dfs_info *) cur->aux)->next_cycle)
	{
	  cgraph_node *node = cur->inlined_to ? cur->inlined_to : cur;
	  modref_summary *cur_summary = optimization_summaries
					? optimization_summaries->get (node)
					: NULL;
	  modref_summary_lto *cur_summary_lto = summaries_lto
						? summaries_lto->get (node)
						: NULL;

	  if (!cur_summary && !cur_summary_lto)
	    continue;
	  int caller_ecf_flags = flags_from_decl_or_type (cur->decl);

	  if (dump_file)
	    fprintf (dump_file, "  Processing %s%s%s\n",
		     cur->dump_name (),
		     TREE_READONLY (cur->decl) ? " (const)" : "",
		     DECL_PURE_P (cur->decl) ? " (pure)" : "");

	  for (cgraph_edge *e = cur->indirect_calls; e; e = e->next_callee)
	    {
	      escape_summary *sum = escape_summaries->get (e);

	      if (!sum || (e->indirect_info->ecf_flags
			   & (ECF_CONST | ECF_NOVOPS)))
		continue;

	      changed |= modref_merge_call_site_flags
				(sum, cur_summary, cur_summary_lto,
				 NULL, NULL,
				 node->decl,
				 e,
				 caller_ecf_flags,
				 e->indirect_info->ecf_flags,
				 false);
	    }

	  if (!cur_summary && !cur_summary_lto)
	    continue;

	  for (cgraph_edge *callee_edge = cur->callees; callee_edge;
	       callee_edge = callee_edge->next_callee)
	    {
	      int ecf_flags = flags_from_decl_or_type
				 (callee_edge->callee->decl);
	      modref_summary *callee_summary = NULL;
	      modref_summary_lto *callee_summary_lto = NULL;
	      struct cgraph_node *callee;

	      if (ecf_flags & (ECF_CONST | ECF_NOVOPS)
		  || !callee_edge->inline_failed)
		continue;

	      /* Get the callee and its summary.  */
	      enum availability avail;
	      callee = callee_edge->callee->ultimate_alias_target
			 (&avail, cur);

	      /* It is not necessary to re-process calls outside of the
		 SCC component.  */
	      if (iteration > 0
		  && (!callee->aux
		      || ((struct ipa_dfs_info *)cur->aux)->scc_no
			  != ((struct ipa_dfs_info *)callee->aux)->scc_no))
		continue;

	      escape_summary *sum = escape_summaries->get (callee_edge);
	      if (!sum)
		continue;

	      if (dump_file)
		fprintf (dump_file, "    Call to %s\n",
			 callee_edge->callee->dump_name ());

	      if (avail <= AVAIL_INTERPOSABLE
		  || callee_edge->call_stmt_cannot_inline_p)
		;
	      else
		{
		  if (cur_summary)
		    callee_summary = optimization_summaries->get (callee);
		  if (cur_summary_lto)
		    callee_summary_lto = summaries_lto->get (callee);
		}
	      changed |= modref_merge_call_site_flags
				(sum, cur_summary, cur_summary_lto,
				 callee_summary, callee_summary_lto,
				 node->decl,
				 callee_edge,
				 caller_ecf_flags,
				 ecf_flags,
				 callee->binds_to_current_def_p ());
	      if (dump_file && changed)
		{
		  if (cur_summary)
		    cur_summary->dump (dump_file);
		  if (cur_summary_lto)
		    cur_summary_lto->dump (dump_file);
		}
	    }
	}
      iteration++;
    }
  if (dump_file)
    fprintf (dump_file,
	     "Propagation of flags finished in %i iterations\n", iteration);
}

}  /* ANON namespace.  */

/* Call EDGE was inlined; merge summary from callee to the caller.  */

void
ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
{
  if (!summaries && !summaries_lto)
    return;

  struct cgraph_node *to = (edge->caller->inlined_to
			    ? edge->caller->inlined_to : edge->caller);
  class modref_summary *to_info = summaries ? summaries->get (to) : NULL;
  class modref_summary_lto *to_info_lto = summaries_lto
					  ? summaries_lto->get (to) : NULL;

  if (!to_info && !to_info_lto)
    {
      if (summaries)
	summaries->remove (edge->callee);
      if (summaries_lto)
	summaries_lto->remove (edge->callee);
      remove_modref_edge_summaries (edge->callee);
      return;
    }

  class modref_summary *callee_info = summaries ? summaries->get (edge->callee)
				      : NULL;
  class modref_summary_lto *callee_info_lto
		 = summaries_lto ? summaries_lto->get (edge->callee) : NULL;
  int flags = flags_from_decl_or_type (edge->callee->decl);
  /* Combine in outer flags.  */
  cgraph_node *n;
  for (n = edge->caller; n->inlined_to; n = n->callers->caller)
    flags |= flags_from_decl_or_type (n->decl);
  flags |= flags_from_decl_or_type (n->decl);
  bool ignore_stores = ignore_stores_p (edge->caller->decl, flags);

  if (!callee_info && to_info)
    {
      if (!(flags & (ECF_CONST | ECF_NOVOPS)))
	to_info->loads->collapse ();
      if (!ignore_stores)
	to_info->stores->collapse ();
    }
  if (!callee_info_lto && to_info_lto)
    {
      if (!(flags & (ECF_CONST | ECF_NOVOPS)))
	to_info_lto->loads->collapse ();
      if (!ignore_stores)
	to_info_lto->stores->collapse ();
    }
  if (callee_info || callee_info_lto)
    {
      auto_vec <modref_parm_map, 32> parm_map;
      modref_parm_map chain_map;
      /* TODO: Once we get jump functions for static chains we could
	 compute parm_index.  */

      compute_parm_map (edge, &parm_map);

      if (!ignore_stores)
	{
	  if (to_info && callee_info)
	    to_info->stores->merge (to->decl, callee_info->stores, &parm_map,
				    &chain_map, false);
	  if (to_info_lto && callee_info_lto)
	    to_info_lto->stores->merge (to->decl, callee_info_lto->stores,
					&parm_map, &chain_map, false);
	}
      if (!(flags & (ECF_CONST | ECF_NOVOPS)))
	{
	  if (to_info && callee_info)
	    to_info->loads->merge (to->decl, callee_info->loads, &parm_map,
				   &chain_map, false);
	  if (to_info_lto && callee_info_lto)
	    to_info_lto->loads->merge (to->decl, callee_info_lto->loads,
				       &parm_map, &chain_map, false);
	}
    }

  /* Now merge escape summaries.
     For every escape to the callee we need to merge calle flags
     and remap calees escapes.  */
  class escape_summary *sum = escape_summaries->get (edge);
  int max_escape = -1;
  escape_entry *ee;
  unsigned int i;

  if (sum && !(flags & (ECF_CONST | ECF_NOVOPS)))
    FOR_EACH_VEC_ELT (sum->esc, i, ee)
      if ((int)ee->arg > max_escape)
	max_escape = ee->arg;

  auto_vec <vec <struct escape_map>, 32> emap (max_escape + 1);
  emap.safe_grow (max_escape + 1, true);
  for (i = 0; (int)i < max_escape + 1; i++)
    emap[i] = vNULL;

  if (sum && !(flags & (ECF_CONST | ECF_NOVOPS)))
    FOR_EACH_VEC_ELT (sum->esc, i, ee)
      {
	bool needed = false;
	int implicit_flags = implicit_eaf_flags_for_edge_and_arg
				(edge, flags, ignore_stores,
				 ee->arg);
	if (!ee->direct)
	  implicit_flags = deref_flags (implicit_flags, ignore_stores);
	if (to_info && (int)to_info->arg_flags.length () > ee->parm_index)
	  {
	    int flags = callee_info
			&& callee_info->arg_flags.length () > ee->arg
			? callee_info->arg_flags[ee->arg] : 0;
	    if (!ee->direct)
	      flags = deref_flags (flags, ignore_stores);
	    flags |= ee->min_flags | implicit_flags;
	    eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM
			     ? to_info->retslot_flags
			     : ee->parm_index == MODREF_STATIC_CHAIN_PARM
			     ? to_info->static_chain_flags
			     : to_info->arg_flags[ee->parm_index];
	    f &= flags;
	    if (f)
	      needed = true;
	  }
	if (to_info_lto
	    && (int)to_info_lto->arg_flags.length () > ee->parm_index)
	  {
	    int flags = callee_info_lto
			&& callee_info_lto->arg_flags.length () > ee->arg
			? callee_info_lto->arg_flags[ee->arg] : 0;
	    if (!ee->direct)
	      flags = deref_flags (flags, ignore_stores);
	    flags |= ee->min_flags | implicit_flags;
	    eaf_flags_t &f = ee->parm_index == MODREF_RETSLOT_PARM
			     ? to_info_lto->retslot_flags
			     : ee->parm_index == MODREF_STATIC_CHAIN_PARM
			     ? to_info_lto->static_chain_flags
			     : to_info_lto->arg_flags[ee->parm_index];
	    f &= flags;
	    if (f)
	      needed = true;
	  }
	struct escape_map entry = {ee->parm_index, ee->direct};
	if (needed)
	  emap[ee->arg].safe_push (entry);
      }
  update_escape_summary (edge->callee, emap, ignore_stores);
  for (i = 0; (int)i < max_escape + 1; i++)
    emap[i].release ();
  if (sum)
    escape_summaries->remove (edge);

  if (summaries)
    {
      if (to_info && !to_info->useful_p (flags))
	{
	  if (dump_file)
	    fprintf (dump_file, "Removed mod-ref summary for %s\n",
		     to->dump_name ());
	  summaries->remove (to);
	  to_info = NULL;
	}
      else if (to_info && dump_file)
	{
	  if (dump_file)
	    fprintf (dump_file, "Updated mod-ref summary for %s\n",
		     to->dump_name ());
	  to_info->dump (dump_file);
	}
      if (callee_info)
	summaries->remove (edge->callee);
    }
  if (summaries_lto)
    {
      if (to_info_lto && !to_info_lto->useful_p (flags))
	{
	  if (dump_file)
	    fprintf (dump_file, "Removed mod-ref summary for %s\n",
		     to->dump_name ());
	  summaries_lto->remove (to);
	  to_info_lto = NULL;
	}
      else if (to_info_lto && dump_file)
	{
	  if (dump_file)
	    fprintf (dump_file, "Updated mod-ref summary for %s\n",
		     to->dump_name ());
	  to_info_lto->dump (dump_file);
	}
      if (callee_info_lto)
	summaries_lto->remove (edge->callee);
    }
  if (!to_info && !to_info_lto)
    remove_modref_edge_summaries (to);
  return;
}

/* Run the IPA pass.  This will take a function's summaries and calls and
   construct new summaries which represent a transitive closure.  So that
   summary of an analyzed function contains information about the loads and
   stores that the function or any function that it calls does.  */

unsigned int
pass_ipa_modref::execute (function *)
{
  if (!summaries && !summaries_lto)
    return 0;
  bool pureconst = false;

  if (optimization_summaries)
    ggc_delete (optimization_summaries);
  optimization_summaries = summaries;
  summaries = NULL;

  struct cgraph_node **order = XCNEWVEC (struct cgraph_node *,
					 symtab->cgraph_count);
  int order_pos;
  order_pos = ipa_reduced_postorder (order, true, ignore_edge);
  int i;

  /* Iterate over all strongly connected components in post-order.  */
  for (i = 0; i < order_pos; i++)
    {
      /* Get the component's representative.  That's just any node in the
	 component from which we can traverse the entire component.  */
      struct cgraph_node *component_node = order[i];

      if (dump_file)
	fprintf (dump_file, "\n\nStart of SCC component\n");

      pureconst |= modref_propagate_in_scc (component_node);
      modref_propagate_flags_in_scc (component_node);
      if (optimization_summaries)
	for (struct cgraph_node *cur = component_node; cur;
	     cur = ((struct ipa_dfs_info *) cur->aux)->next_cycle)
	  if (modref_summary *sum = optimization_summaries->get (cur))
	    sum->finalize (cur->decl);
      if (dump_file)
	modref_propagate_dump_scc (component_node);
    }
  cgraph_node *node;
  FOR_EACH_FUNCTION (node)
    update_signature (node);
  if (summaries_lto)
    ((modref_summaries_lto *)summaries_lto)->propagated = true;
  ipa_free_postorder_info ();
  free (order);
  delete fnspec_summaries;
  fnspec_summaries = NULL;
  delete escape_summaries;
  escape_summaries = NULL;

  /* If we posibly made constructors const/pure we may need to remove
     them.  */
  return pureconst ? TODO_remove_functions : 0;
}

/* Summaries must stay alive until end of compilation.  */

void
ipa_modref_cc_finalize ()
{
  if (optimization_summaries)
    ggc_delete (optimization_summaries);
  optimization_summaries = NULL;
  if (summaries_lto)
    ggc_delete (summaries_lto);
  summaries_lto = NULL;
  if (fnspec_summaries)
    delete fnspec_summaries;
  fnspec_summaries = NULL;
  if (escape_summaries)
    delete escape_summaries;
  escape_summaries = NULL;
}

#include "gt-ipa-modref.h"
