/* 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-structalias).
	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 parameters
       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.  */
  void duplicate (cgraph_edge *,
		  cgraph_edge *,
		  fnspec_summary *src,
		  fnspec_summary *dst) final override
  {
    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.  */
  void duplicate (cgraph_edge *,
		  cgraph_edge *,
		  escape_summary *src,
		  escape_summary *dst) final override
  {
    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) {}
  void insert (cgraph_node *, modref_summary *state) final override;
  void duplicate (cgraph_node *src_node,
		  cgraph_node *dst_node,
		  modref_summary *src_data,
		  modref_summary *dst_data) final override;
  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) {}
  void insert (cgraph_node *, modref_summary_lto *state) final override;
  void duplicate (cgraph_node *src_node,
		  cgraph_node *dst_node,
		  modref_summary_lto *src_data,
		  modref_summary_lto *dst_data) final override;
  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 analyze 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 nondeterminism 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 either with m_summary or m_summary_lto.  Never on both.  */
  modref_summary *m_summary;
  modref_summary_lto *m_summary_lto;
  /* Recursive calls needs simplistic 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 analyzed.  */
  int m_ecf_flags;
  /* True if IPA propagation will be done later.  */
  bool m_ipa;
  /* Set true if statement currently analyze is known to be
     executed each time function is called.  */
  bool m_always_executed;
};

/* Set side_effects flag and return if something 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 something 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 global 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 global 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/stores across 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 behavior.  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 useless 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 dataflow 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
     escape points if local analysis did good job already).  */
  eaf_flags_t min_flags;
  /* Does value escape directly or indirectly?  */
  bool direct;
};

/* Lattice used during the eaf flags analysis 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 dataflow.  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 obviously 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 anything 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 anything 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 generally 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 recursion 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 solver.  */
  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 are
     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 their 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 dereferences 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 analyzing 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 bookkeeping.  */
  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 iterative 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 escape points.
   PAST_FLAGS, PAST_RETSLOT_FLAGS, PAST_STATIC_CHAIN_FLAGS can be
   used to preserve flags from previous (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 () final override
    {
      return new pass_modref (m_ctxt);
    }
    bool gate (function *) final override
    {
      return flag_ipa_modref;
    }
    unsigned int execute (function *) final override;
};

/* 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 according 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 () final override { return new pass_ipa_modref (m_ctxt); }
  bool gate (function *) final override
  {
    return true;
  }
  unsigned int execute (function *) final override;

};

}

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 for 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 summaries 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 ();
    }
  /* 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 (to_info)
	{
	  if (!callee_info || callee_info->side_effects)
	    to_info->side_effects = true;
	  if ((!callee_info || callee_info->nondeterministic)
	      && !ignore_nondeterminism_p (edge->caller->decl, flags))
	    to_info->nondeterministic = true;
	}
      if (to_info_lto)
	{
	  if (!callee_info_lto || callee_info_lto->side_effects)
	    to_info_lto->side_effects = true;
	  if ((!callee_info_lto || callee_info_lto->nondeterministic)
	      && !ignore_nondeterminism_p (edge->caller->decl, flags))
	    to_info_lto->nondeterministic = true;
	}
     }
  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 callee flags
     and remap callee's 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 possibly 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"
