/* Scalar Replacement of Aggregates (SRA) converts some structure
   references into scalar references, exposing them to the scalar
   optimizers.
   Copyright (C) 2008-2019 Free Software Foundation, Inc.
   Contributed by Martin Jambor <mjambor@suse.cz>

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/>.  */

/* This file implements Scalar Reduction of Aggregates (SRA).  SRA is run
   twice, once in the early stages of compilation (early SRA) and once in the
   late stages (late SRA).  The aim of both is to turn references to scalar
   parts of aggregates into uses of independent scalar variables.

   The two passes are nearly identical, the only difference is that early SRA
   does not scalarize unions which are used as the result in a GIMPLE_RETURN
   statement because together with inlining this can lead to weird type
   conversions.

   Both passes operate in four stages:

   1. The declarations that have properties which make them candidates for
      scalarization are identified in function find_var_candidates().  The
      candidates are stored in candidate_bitmap.

   2. The function body is scanned.  In the process, declarations which are
      used in a manner that prevent their scalarization are removed from the
      candidate bitmap.  More importantly, for every access into an aggregate,
      an access structure (struct access) is created by create_access() and
      stored in a vector associated with the aggregate.  Among other
      information, the aggregate declaration, the offset and size of the access
      and its type are stored in the structure.

      On a related note, assign_link structures are created for every assign
      statement between candidate aggregates and attached to the related
      accesses.

   3. The vectors of accesses are analyzed.  They are first sorted according to
      their offset and size and then scanned for partially overlapping accesses
      (i.e. those which overlap but one is not entirely within another).  Such
      an access disqualifies the whole aggregate from being scalarized.

      If there is no such inhibiting overlap, a representative access structure
      is chosen for every unique combination of offset and size.  Afterwards,
      the pass builds a set of trees from these structures, in which children
      of an access are within their parent (in terms of offset and size).

      Then accesses  are propagated  whenever possible (i.e.  in cases  when it
      does not create a partially overlapping access) across assign_links from
      the right hand side to the left hand side.

      Then the set of trees for each declaration is traversed again and those
      accesses which should be replaced by a scalar are identified.

   4. The function is traversed again, and for every reference into an
      aggregate that has some component which is about to be scalarized,
      statements are amended and new statements are created as necessary.
      Finally, if a parameter got scalarized, the scalar replacements are
      initialized with values from respective parameter aggregates.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "predict.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "gimple-pretty-print.h"
#include "alias.h"
#include "fold-const.h"
#include "tree-eh.h"
#include "stor-layout.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "gimple-walk.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "symbol-summary.h"
#include "ipa-param-manipulation.h"
#include "ipa-prop.h"
#include "params.h"
#include "dbgcnt.h"
#include "tree-inline.h"
#include "ipa-fnsummary.h"
#include "ipa-utils.h"
#include "builtins.h"

/* Enumeration of all aggregate reductions we can do.  */
enum sra_mode { SRA_MODE_EARLY_IPA,   /* early call regularization */
		SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
		SRA_MODE_INTRA };     /* late intraprocedural SRA */

/* Global variable describing which aggregate reduction we are performing at
   the moment.  */
static enum sra_mode sra_mode;

struct assign_link;

/* ACCESS represents each access to an aggregate variable (as a whole or a
   part).  It can also represent a group of accesses that refer to exactly the
   same fragment of an aggregate (i.e. those that have exactly the same offset
   and size).  Such representatives for a single aggregate, once determined,
   are linked in a linked list and have the group fields set.

   Moreover, when doing intraprocedural SRA, a tree is built from those
   representatives (by the means of first_child and next_sibling pointers), in
   which all items in a subtree are "within" the root, i.e. their offset is
   greater or equal to offset of the root and offset+size is smaller or equal
   to offset+size of the root.  Children of an access are sorted by offset.

   Note that accesses to parts of vector and complex number types always
   represented by an access to the whole complex number or a vector.  It is a
   duty of the modifying functions to replace them appropriately.  */

struct access
{
  /* Values returned by  `get_ref_base_and_extent' for each component reference
     If EXPR isn't a component reference  just set `BASE = EXPR', `OFFSET = 0',
     `SIZE = TREE_SIZE (TREE_TYPE (expr))'.  */
  HOST_WIDE_INT offset;
  HOST_WIDE_INT size;
  tree base;

  /* Expression.  It is context dependent so do not use it to create new
     expressions to access the original aggregate.  See PR 42154 for a
     testcase.  */
  tree expr;
  /* Type.  */
  tree type;

  /* The statement this access belongs to.  */
  gimple *stmt;

  /* Next group representative for this aggregate. */
  struct access *next_grp;

  /* Pointer to the group representative.  Pointer to itself if the struct is
     the representative.  */
  struct access *group_representative;

  /* After access tree has been constructed, this points to the parent of the
     current access, if there is one.  NULL for roots.  */
  struct access *parent;

  /* If this access has any children (in terms of the definition above), this
     points to the first one.  */
  struct access *first_child;

  /* In intraprocedural SRA, pointer to the next sibling in the access tree as
     described above.  In IPA-SRA this is a pointer to the next access
     belonging to the same group (having the same representative).  */
  struct access *next_sibling;

  /* Pointers to the first and last element in the linked list of assign
     links.  */
  struct assign_link *first_link, *last_link;

  /* Pointer to the next access in the work queue.  */
  struct access *next_queued;

  /* Replacement variable for this access "region."  Never to be accessed
     directly, always only by the means of get_access_replacement() and only
     when grp_to_be_replaced flag is set.  */
  tree replacement_decl;

  /* Is this access an access to a non-addressable field? */
  unsigned non_addressable : 1;

  /* Is this access made in reverse storage order? */
  unsigned reverse : 1;

  /* Is this particular access write access? */
  unsigned write : 1;

  /* Is this access currently in the work queue?  */
  unsigned grp_queued : 1;

  /* Does this group contain a write access?  This flag is propagated down the
     access tree.  */
  unsigned grp_write : 1;

  /* Does this group contain a read access?  This flag is propagated down the
     access tree.  */
  unsigned grp_read : 1;

  /* Does this group contain a read access that comes from an assignment
     statement?  This flag is propagated down the access tree.  */
  unsigned grp_assignment_read : 1;

  /* Does this group contain a write access that comes from an assignment
     statement?  This flag is propagated down the access tree.  */
  unsigned grp_assignment_write : 1;

  /* Does this group contain a read access through a scalar type?  This flag is
     not propagated in the access tree in any direction.  */
  unsigned grp_scalar_read : 1;

  /* Does this group contain a write access through a scalar type?  This flag
     is not propagated in the access tree in any direction.  */
  unsigned grp_scalar_write : 1;

  /* Is this access an artificial one created to scalarize some record
     entirely? */
  unsigned grp_total_scalarization : 1;

  /* Other passes of the analysis use this bit to make function
     analyze_access_subtree create scalar replacements for this group if
     possible.  */
  unsigned grp_hint : 1;

  /* Is the subtree rooted in this access fully covered by scalar
     replacements?  */
  unsigned grp_covered : 1;

  /* If set to true, this access and all below it in an access tree must not be
     scalarized.  */
  unsigned grp_unscalarizable_region : 1;

  /* Whether data have been written to parts of the aggregate covered by this
     access which is not to be scalarized.  This flag is propagated up in the
     access tree.  */
  unsigned grp_unscalarized_data : 1;

  /* Does this access and/or group contain a write access through a
     BIT_FIELD_REF?  */
  unsigned grp_partial_lhs : 1;

  /* Set when a scalar replacement should be created for this variable.  */
  unsigned grp_to_be_replaced : 1;

  /* Set when we want a replacement for the sole purpose of having it in
     generated debug statements.  */
  unsigned grp_to_be_debug_replaced : 1;

  /* Should TREE_NO_WARNING of a replacement be set?  */
  unsigned grp_no_warning : 1;

  /* Is it possible that the group refers to data which might be (directly or
     otherwise) modified?  */
  unsigned grp_maybe_modified : 1;

  /* Set when this is a representative of a pointer to scalar (i.e. by
     reference) parameter which we consider for turning into a plain scalar
     (i.e. a by value parameter).  */
  unsigned grp_scalar_ptr : 1;

  /* Set when we discover that this pointer is not safe to dereference in the
     caller.  */
  unsigned grp_not_necessarilly_dereferenced : 1;
};

typedef struct access *access_p;


/* Alloc pool for allocating access structures.  */
static object_allocator<struct access> access_pool ("SRA accesses");

/* A structure linking lhs and rhs accesses from an aggregate assignment.  They
   are used to propagate subaccesses from rhs to lhs as long as they don't
   conflict with what is already there.  */
struct assign_link
{
  struct access *lacc, *racc;
  struct assign_link *next;
};

/* Alloc pool for allocating assign link structures.  */
static object_allocator<assign_link> assign_link_pool ("SRA links");

/* Base (tree) -> Vector (vec<access_p> *) map.  */
static hash_map<tree, auto_vec<access_p> > *base_access_vec;

/* Hash to limit creation of artificial accesses */
static hash_map<tree, unsigned> *propagation_budget;

/* Candidate hash table helpers.  */

struct uid_decl_hasher : nofree_ptr_hash <tree_node>
{
  static inline hashval_t hash (const tree_node *);
  static inline bool equal (const tree_node *, const tree_node *);
};

/* Hash a tree in a uid_decl_map.  */

inline hashval_t
uid_decl_hasher::hash (const tree_node *item)
{
  return item->decl_minimal.uid;
}

/* Return true if the DECL_UID in both trees are equal.  */

inline bool
uid_decl_hasher::equal (const tree_node *a, const tree_node *b)
{
  return (a->decl_minimal.uid == b->decl_minimal.uid);
}

/* Set of candidates.  */
static bitmap candidate_bitmap;
static hash_table<uid_decl_hasher> *candidates;

/* For a candidate UID return the candidates decl.  */

static inline tree
candidate (unsigned uid)
{
 tree_node t;
 t.decl_minimal.uid = uid;
 return candidates->find_with_hash (&t, static_cast <hashval_t> (uid));
}

/* Bitmap of candidates which we should try to entirely scalarize away and
   those which cannot be (because they are and need be used as a whole).  */
static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;

/* Bitmap of candidates in the constant pool, which cannot be scalarized
   because this would produce non-constant expressions (e.g. Ada).  */
static bitmap disqualified_constants;

/* Obstack for creation of fancy names.  */
static struct obstack name_obstack;

/* Head of a linked list of accesses that need to have its subaccesses
   propagated to their assignment counterparts. */
static struct access *work_queue_head;

/* Number of parameters of the analyzed function when doing early ipa SRA.  */
static int func_param_count;

/* scan_function sets the following to true if it encounters a call to
   __builtin_apply_args.  */
static bool encountered_apply_args;

/* Set by scan_function when it finds a recursive call.  */
static bool encountered_recursive_call;

/* Set by scan_function when it finds a recursive call with less actual
   arguments than formal parameters..  */
static bool encountered_unchangable_recursive_call;

/* This is a table in which for each basic block and parameter there is a
   distance (offset + size) in that parameter which is dereferenced and
   accessed in that BB.  */
static HOST_WIDE_INT *bb_dereferences;
/* Bitmap of BBs that can cause the function to "stop" progressing by
   returning, throwing externally, looping infinitely or calling a function
   which might abort etc.. */
static bitmap final_bbs;

/* Representative of no accesses at all. */
static struct access  no_accesses_representant;

/* Predicate to test the special value.  */

static inline bool
no_accesses_p (struct access *access)
{
  return access == &no_accesses_representant;
}

/* Dump contents of ACCESS to file F in a human friendly way.  If GRP is true,
   representative fields are dumped, otherwise those which only describe the
   individual access are.  */

static struct
{
  /* Number of processed aggregates is readily available in
     analyze_all_variable_accesses and so is not stored here.  */

  /* Number of created scalar replacements.  */
  int replacements;

  /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
     expression.  */
  int exprs;

  /* Number of statements created by generate_subtree_copies.  */
  int subtree_copies;

  /* Number of statements created by load_assign_lhs_subreplacements.  */
  int subreplacements;

  /* Number of times sra_modify_assign has deleted a statement.  */
  int deleted;

  /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
     RHS reparately due to type conversions or nonexistent matching
     references.  */
  int separate_lhs_rhs_handling;

  /* Number of parameters that were removed because they were unused.  */
  int deleted_unused_parameters;

  /* Number of scalars passed as parameters by reference that have been
     converted to be passed by value.  */
  int scalar_by_ref_to_by_val;

  /* Number of aggregate parameters that were replaced by one or more of their
     components.  */
  int aggregate_params_reduced;

  /* Numbber of components created when splitting aggregate parameters.  */
  int param_reductions_created;
} sra_stats;

static void
dump_access (FILE *f, struct access *access, bool grp)
{
  fprintf (f, "access { ");
  fprintf (f, "base = (%d)'", DECL_UID (access->base));
  print_generic_expr (f, access->base);
  fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
  fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
  fprintf (f, ", expr = ");
  print_generic_expr (f, access->expr);
  fprintf (f, ", type = ");
  print_generic_expr (f, access->type);
  fprintf (f, ", non_addressable = %d, reverse = %d",
	   access->non_addressable, access->reverse);
  if (grp)
    fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
	     "grp_assignment_write = %d, grp_scalar_read = %d, "
	     "grp_scalar_write = %d, grp_total_scalarization = %d, "
	     "grp_hint = %d, grp_covered = %d, "
	     "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
	     "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
	     "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
	     "grp_not_necessarilly_dereferenced = %d\n",
	     access->grp_read, access->grp_write, access->grp_assignment_read,
	     access->grp_assignment_write, access->grp_scalar_read,
	     access->grp_scalar_write, access->grp_total_scalarization,
	     access->grp_hint, access->grp_covered,
	     access->grp_unscalarizable_region, access->grp_unscalarized_data,
	     access->grp_partial_lhs, access->grp_to_be_replaced,
	     access->grp_to_be_debug_replaced, access->grp_maybe_modified,
	     access->grp_not_necessarilly_dereferenced);
  else
    fprintf (f, ", write = %d, grp_total_scalarization = %d, "
	     "grp_partial_lhs = %d\n",
	     access->write, access->grp_total_scalarization,
	     access->grp_partial_lhs);
}

/* Dump a subtree rooted in ACCESS to file F, indent by LEVEL.  */

static void
dump_access_tree_1 (FILE *f, struct access *access, int level)
{
  do
    {
      int i;

      for (i = 0; i < level; i++)
	fputs ("* ", f);

      dump_access (f, access, true);

      if (access->first_child)
	dump_access_tree_1 (f, access->first_child, level + 1);

      access = access->next_sibling;
    }
  while (access);
}

/* Dump all access trees for a variable, given the pointer to the first root in
   ACCESS.  */

static void
dump_access_tree (FILE *f, struct access *access)
{
  for (; access; access = access->next_grp)
    dump_access_tree_1 (f, access, 0);
}

/* Return true iff ACC is non-NULL and has subaccesses.  */

static inline bool
access_has_children_p (struct access *acc)
{
  return acc && acc->first_child;
}

/* Return true iff ACC is (partly) covered by at least one replacement.  */

static bool
access_has_replacements_p (struct access *acc)
{
  struct access *child;
  if (acc->grp_to_be_replaced)
    return true;
  for (child = acc->first_child; child; child = child->next_sibling)
    if (access_has_replacements_p (child))
      return true;
  return false;
}

/* Return a vector of pointers to accesses for the variable given in BASE or
   NULL if there is none.  */

static vec<access_p> *
get_base_access_vector (tree base)
{
  return base_access_vec->get (base);
}

/* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
   in ACCESS.  Return NULL if it cannot be found.  */

static struct access *
find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
			HOST_WIDE_INT size)
{
  while (access && (access->offset != offset || access->size != size))
    {
      struct access *child = access->first_child;

      while (child && (child->offset + child->size <= offset))
	child = child->next_sibling;
      access = child;
    }

  return access;
}

/* Return the first group representative for DECL or NULL if none exists.  */

static struct access *
get_first_repr_for_decl (tree base)
{
  vec<access_p> *access_vec;

  access_vec = get_base_access_vector (base);
  if (!access_vec)
    return NULL;

  return (*access_vec)[0];
}

/* Find an access representative for the variable BASE and given OFFSET and
   SIZE.  Requires that access trees have already been built.  Return NULL if
   it cannot be found.  */

static struct access *
get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
				 HOST_WIDE_INT size)
{
  struct access *access;

  access = get_first_repr_for_decl (base);
  while (access && (access->offset + access->size <= offset))
    access = access->next_grp;
  if (!access)
    return NULL;

  return find_access_in_subtree (access, offset, size);
}

/* Add LINK to the linked list of assign links of RACC.  */
static void
add_link_to_rhs (struct access *racc, struct assign_link *link)
{
  gcc_assert (link->racc == racc);

  if (!racc->first_link)
    {
      gcc_assert (!racc->last_link);
      racc->first_link = link;
    }
  else
    racc->last_link->next = link;

  racc->last_link = link;
  link->next = NULL;
}

/* Move all link structures in their linked list in OLD_RACC to the linked list
   in NEW_RACC.  */
static void
relink_to_new_repr (struct access *new_racc, struct access *old_racc)
{
  if (!old_racc->first_link)
    {
      gcc_assert (!old_racc->last_link);
      return;
    }

  if (new_racc->first_link)
    {
      gcc_assert (!new_racc->last_link->next);
      gcc_assert (!old_racc->last_link || !old_racc->last_link->next);

      new_racc->last_link->next = old_racc->first_link;
      new_racc->last_link = old_racc->last_link;
    }
  else
    {
      gcc_assert (!new_racc->last_link);

      new_racc->first_link = old_racc->first_link;
      new_racc->last_link = old_racc->last_link;
    }
  old_racc->first_link = old_racc->last_link = NULL;
}

/* Add ACCESS to the work queue (which is actually a stack).  */

static void
add_access_to_work_queue (struct access *access)
{
  if (access->first_link && !access->grp_queued)
    {
      gcc_assert (!access->next_queued);
      access->next_queued = work_queue_head;
      access->grp_queued = 1;
      work_queue_head = access;
    }
}

/* Pop an access from the work queue, and return it, assuming there is one.  */

static struct access *
pop_access_from_work_queue (void)
{
  struct access *access = work_queue_head;

  work_queue_head = access->next_queued;
  access->next_queued = NULL;
  access->grp_queued = 0;
  return access;
}


/* Allocate necessary structures.  */

static void
sra_initialize (void)
{
  candidate_bitmap = BITMAP_ALLOC (NULL);
  candidates = new hash_table<uid_decl_hasher>
    (vec_safe_length (cfun->local_decls) / 2);
  should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
  cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
  disqualified_constants = BITMAP_ALLOC (NULL);
  gcc_obstack_init (&name_obstack);
  base_access_vec = new hash_map<tree, auto_vec<access_p> >;
  memset (&sra_stats, 0, sizeof (sra_stats));
  encountered_apply_args = false;
  encountered_recursive_call = false;
  encountered_unchangable_recursive_call = false;
}

/* Deallocate all general structures.  */

static void
sra_deinitialize (void)
{
  BITMAP_FREE (candidate_bitmap);
  delete candidates;
  candidates = NULL;
  BITMAP_FREE (should_scalarize_away_bitmap);
  BITMAP_FREE (cannot_scalarize_away_bitmap);
  BITMAP_FREE (disqualified_constants);
  access_pool.release ();
  assign_link_pool.release ();
  obstack_free (&name_obstack, NULL);

  delete base_access_vec;
}

/* Return true if DECL is a VAR_DECL in the constant pool, false otherwise.  */

static bool constant_decl_p (tree decl)
{
  return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl);
}

/* Remove DECL from candidates for SRA and write REASON to the dump file if
   there is one.  */

static void
disqualify_candidate (tree decl, const char *reason)
{
  if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
    candidates->remove_elt_with_hash (decl, DECL_UID (decl));
  if (constant_decl_p (decl))
    bitmap_set_bit (disqualified_constants, DECL_UID (decl));

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "! Disqualifying ");
      print_generic_expr (dump_file, decl);
      fprintf (dump_file, " - %s\n", reason);
    }
}

/* Return true iff the type contains a field or an element which does not allow
   scalarization.  */

static bool
type_internals_preclude_sra_p (tree type, const char **msg)
{
  tree fld;
  tree et;

  switch (TREE_CODE (type))
    {
    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
	if (TREE_CODE (fld) == FIELD_DECL)
	  {
	    tree ft = TREE_TYPE (fld);

	    if (TREE_THIS_VOLATILE (fld))
	      {
		*msg = "volatile structure field";
		return true;
	      }
	    if (!DECL_FIELD_OFFSET (fld))
	      {
		*msg = "no structure field offset";
		return true;
	      }
	    if (!DECL_SIZE (fld))
	      {
		*msg = "zero structure field size";
	        return true;
	      }
	    if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
	      {
		*msg = "structure field offset not fixed";
		return true;
	      }
	    if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
	      {
	        *msg = "structure field size not fixed";
		return true;
	      }
	    if (!tree_fits_shwi_p (bit_position (fld)))
	      {
	        *msg = "structure field size too big";
		return true;
	      }
	    if (AGGREGATE_TYPE_P (ft)
		    && int_bit_position (fld) % BITS_PER_UNIT != 0)
	      {
		*msg = "structure field is bit field";
	        return true;
	      }

	    if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
	      return true;
	  }

      return false;

    case ARRAY_TYPE:
      et = TREE_TYPE (type);

      if (TYPE_VOLATILE (et))
	{
	  *msg = "element type is volatile";
	  return true;
	}

      if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
	return true;

      return false;

    default:
      return false;
    }
}

/* If T is an SSA_NAME, return NULL if it is not a default def or return its
   base variable if it is.  Return T if it is not an SSA_NAME.  */

static tree
get_ssa_base_param (tree t)
{
  if (TREE_CODE (t) == SSA_NAME)
    {
      if (SSA_NAME_IS_DEFAULT_DEF (t))
	return SSA_NAME_VAR (t);
      else
	return NULL_TREE;
    }
  return t;
}

/* Mark a dereference of BASE of distance DIST in a basic block tht STMT
   belongs to, unless the BB has already been marked as a potentially
   final.  */

static void
mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple *stmt)
{
  basic_block bb = gimple_bb (stmt);
  int idx, parm_index = 0;
  tree parm;

  if (bitmap_bit_p (final_bbs, bb->index))
    return;

  for (parm = DECL_ARGUMENTS (current_function_decl);
       parm && parm != base;
       parm = DECL_CHAIN (parm))
    parm_index++;

  gcc_assert (parm_index < func_param_count);

  idx = bb->index * func_param_count + parm_index;
  if (bb_dereferences[idx] < dist)
    bb_dereferences[idx] = dist;
}

/* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
   the three fields.  Also add it to the vector of accesses corresponding to
   the base.  Finally, return the new access.  */

static struct access *
create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
{
  struct access *access = access_pool.allocate ();

  memset (access, 0, sizeof (struct access));
  access->base = base;
  access->offset = offset;
  access->size = size;

  base_access_vec->get_or_insert (base).safe_push (access);

  return access;
}

static bool maybe_add_sra_candidate (tree);

/* Create and insert access for EXPR. Return created access, or NULL if it is
   not possible.  Also scan for uses of constant pool as we go along and add
   to candidates.  */

static struct access *
create_access (tree expr, gimple *stmt, bool write)
{
  struct access *access;
  poly_int64 poffset, psize, pmax_size;
  HOST_WIDE_INT offset, size, max_size;
  tree base = expr;
  bool reverse, ptr, unscalarizable_region = false;

  base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size,
				  &reverse);
  if (!poffset.is_constant (&offset)
      || !psize.is_constant (&size)
      || !pmax_size.is_constant (&max_size))
    {
      disqualify_candidate (base, "Encountered a polynomial-sized access.");
      return NULL;
    }

  if (sra_mode == SRA_MODE_EARLY_IPA
      && TREE_CODE (base) == MEM_REF)
    {
      base = get_ssa_base_param (TREE_OPERAND (base, 0));
      if (!base)
	return NULL;
      ptr = true;
    }
  else
    ptr = false;

  /* For constant-pool entries, check we can substitute the constant value.  */
  if (constant_decl_p (base)
      && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA))
    {
      gcc_assert (!bitmap_bit_p (disqualified_constants, DECL_UID (base)));
      if (expr != base
	  && !is_gimple_reg_type (TREE_TYPE (expr))
	  && dump_file && (dump_flags & TDF_DETAILS))
	{
	  /* This occurs in Ada with accesses to ARRAY_RANGE_REFs,
	     and elements of multidimensional arrays (which are
	     multi-element arrays in their own right).  */
	  fprintf (dump_file, "Allowing non-reg-type load of part"
			      " of constant-pool entry: ");
	  print_generic_expr (dump_file, expr);
	}
      maybe_add_sra_candidate (base);
    }

  if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
    return NULL;

  if (sra_mode == SRA_MODE_EARLY_IPA)
    {
      if (size < 0 || size != max_size)
	{
	  disqualify_candidate (base, "Encountered a variable sized access.");
	  return NULL;
	}
      if (TREE_CODE (expr) == COMPONENT_REF
	  && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
	{
	  disqualify_candidate (base, "Encountered a bit-field access.");
	  return NULL;
	}
      gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);

      if (ptr)
	mark_parm_dereference (base, offset + size, stmt);
    }
  else
    {
      if (size != max_size)
	{
	  size = max_size;
	  unscalarizable_region = true;
	}
      if (size < 0)
	{
	  disqualify_candidate (base, "Encountered an unconstrained access.");
	  return NULL;
	}
    }

  access = create_access_1 (base, offset, size);
  access->expr = expr;
  access->type = TREE_TYPE (expr);
  access->write = write;
  access->grp_unscalarizable_region = unscalarizable_region;
  access->stmt = stmt;
  access->reverse = reverse;

  if (TREE_CODE (expr) == COMPONENT_REF
      && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
    access->non_addressable = 1;

  return access;
}


/* Return true iff TYPE is scalarizable - i.e. a RECORD_TYPE or fixed-length
   ARRAY_TYPE with fields that are either of gimple register types (excluding
   bit-fields) or (recursively) scalarizable types.  CONST_DECL must be true if
   we are considering a decl from constant pool.  If it is false, char arrays
   will be refused.  */

static bool
scalarizable_type_p (tree type, bool const_decl)
{
  gcc_assert (!is_gimple_reg_type (type));
  if (type_contains_placeholder_p (type))
    return false;

  switch (TREE_CODE (type))
  {
  case RECORD_TYPE:
    for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
      if (TREE_CODE (fld) == FIELD_DECL)
	{
	  tree ft = TREE_TYPE (fld);

	  if (DECL_BIT_FIELD (fld))
	    return false;

	  if (!is_gimple_reg_type (ft)
	      && !scalarizable_type_p (ft, const_decl))
	    return false;
	}

    return true;

  case ARRAY_TYPE:
    {
      HOST_WIDE_INT min_elem_size;
      if (const_decl)
	min_elem_size = 0;
      else
	min_elem_size = BITS_PER_UNIT;

      if (TYPE_DOMAIN (type) == NULL_TREE
	  || !tree_fits_shwi_p (TYPE_SIZE (type))
	  || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type)))
	  || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= min_elem_size)
	  || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
	return false;
      if (tree_to_shwi (TYPE_SIZE (type)) == 0
	  && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE)
	/* Zero-element array, should not prevent scalarization.  */
	;
      else if ((tree_to_shwi (TYPE_SIZE (type)) <= 0)
	       || !tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
	/* Variable-length array, do not allow scalarization.  */
	return false;

      tree elem = TREE_TYPE (type);
      if (!is_gimple_reg_type (elem)
	  && !scalarizable_type_p (elem, const_decl))
	return false;
      return true;
    }
  default:
    return false;
  }
}

static void scalarize_elem (tree, HOST_WIDE_INT, HOST_WIDE_INT, bool, tree, tree);

/* Create total_scalarization accesses for all scalar fields of a member
   of type DECL_TYPE conforming to scalarizable_type_p.  BASE
   must be the top-most VAR_DECL representing the variable; within that,
   OFFSET locates the member and REF must be the memory reference expression for
   the member.  */

static void
completely_scalarize (tree base, tree decl_type, HOST_WIDE_INT offset, tree ref)
{
  switch (TREE_CODE (decl_type))
    {
    case RECORD_TYPE:
      for (tree fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
	if (TREE_CODE (fld) == FIELD_DECL)
	  {
	    HOST_WIDE_INT pos = offset + int_bit_position (fld);
	    tree ft = TREE_TYPE (fld);
	    tree nref = build3 (COMPONENT_REF, ft, ref, fld, NULL_TREE);

	    scalarize_elem (base, pos, tree_to_uhwi (DECL_SIZE (fld)),
			    TYPE_REVERSE_STORAGE_ORDER (decl_type),
			    nref, ft);
	  }
      break;
    case ARRAY_TYPE:
      {
	tree elemtype = TREE_TYPE (decl_type);
	tree elem_size = TYPE_SIZE (elemtype);
	gcc_assert (elem_size && tree_fits_shwi_p (elem_size));
	HOST_WIDE_INT el_size = tree_to_shwi (elem_size);
	gcc_assert (el_size > 0);

	tree minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (decl_type));
	gcc_assert (TREE_CODE (minidx) == INTEGER_CST);
	tree maxidx = TYPE_MAX_VALUE (TYPE_DOMAIN (decl_type));
	/* Skip (some) zero-length arrays; others have MAXIDX == MINIDX - 1.  */
	if (maxidx)
	  {
	    gcc_assert (TREE_CODE (maxidx) == INTEGER_CST);
	    tree domain = TYPE_DOMAIN (decl_type);
	    /* MINIDX and MAXIDX are inclusive, and must be interpreted in
	       DOMAIN (e.g. signed int, whereas min/max may be size_int).  */
	    offset_int idx = wi::to_offset (minidx);
	    offset_int max = wi::to_offset (maxidx);
	    if (!TYPE_UNSIGNED (domain))
	      {
		idx = wi::sext (idx, TYPE_PRECISION (domain));
		max = wi::sext (max, TYPE_PRECISION (domain));
	      }
	    for (int el_off = offset; idx <= max; ++idx)
	      {
		tree nref = build4 (ARRAY_REF, elemtype,
				    ref,
				    wide_int_to_tree (domain, idx),
				    NULL_TREE, NULL_TREE);
		scalarize_elem (base, el_off, el_size,
				TYPE_REVERSE_STORAGE_ORDER (decl_type),
				nref, elemtype);
		el_off += el_size;
	      }
	  }
      }
      break;
    default:
      gcc_unreachable ();
    }
}

/* Create total_scalarization accesses for a member of type TYPE, which must
   satisfy either is_gimple_reg_type or scalarizable_type_p.  BASE must be the
   top-most VAR_DECL representing the variable; within that, POS and SIZE locate
   the member, REVERSE gives its torage order. and REF must be the reference
   expression for it.  */

static void
scalarize_elem (tree base, HOST_WIDE_INT pos, HOST_WIDE_INT size, bool reverse,
		tree ref, tree type)
{
  if (is_gimple_reg_type (type))
  {
    struct access *access = create_access_1 (base, pos, size);
    access->expr = ref;
    access->type = type;
    access->grp_total_scalarization = 1;
    access->reverse = reverse;
    /* Accesses for intraprocedural SRA can have their stmt NULL.  */
  }
  else
    completely_scalarize (base, type, pos, ref);
}

/* Create a total_scalarization access for VAR as a whole.  VAR must be of a
   RECORD_TYPE or ARRAY_TYPE conforming to scalarizable_type_p.  */

static void
create_total_scalarization_access (tree var)
{
  HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
  struct access *access;

  access = create_access_1 (var, 0, size);
  access->expr = var;
  access->type = TREE_TYPE (var);
  access->grp_total_scalarization = 1;
}

/* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it.  */

static inline bool
contains_view_convert_expr_p (const_tree ref)
{
  while (handled_component_p (ref))
    {
      if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
	return true;
      ref = TREE_OPERAND (ref, 0);
    }

  return false;
}

/* Return true if REF contains a VIEW_CONVERT_EXPR or a COMPONENT_REF with a
   bit-field field declaration.  If TYPE_CHANGING_P is non-NULL, set the bool
   it points to will be set if REF contains any of the above or a MEM_REF
   expression that effectively performs type conversion.  */

static bool
contains_vce_or_bfcref_p (const_tree ref, bool *type_changing_p = NULL)
{
  while (handled_component_p (ref))
    {
      if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
	  || (TREE_CODE (ref) == COMPONENT_REF
	      && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
	{
	  if (type_changing_p)
	    *type_changing_p = true;
	  return true;
	}
      ref = TREE_OPERAND (ref, 0);
    }

  if (!type_changing_p
      || TREE_CODE (ref) != MEM_REF
      || TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR)
    return false;

  tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
  if (TYPE_MAIN_VARIANT (TREE_TYPE (ref))
      != TYPE_MAIN_VARIANT (TREE_TYPE (mem)))
    *type_changing_p = true;

  return false;
}

/* Search the given tree for a declaration by skipping handled components and
   exclude it from the candidates.  */

static void
disqualify_base_of_expr (tree t, const char *reason)
{
  t = get_base_address (t);
  if (sra_mode == SRA_MODE_EARLY_IPA
      && TREE_CODE (t) == MEM_REF)
    t = get_ssa_base_param (TREE_OPERAND (t, 0));

  if (t && DECL_P (t))
    disqualify_candidate (t, reason);
}

/* Scan expression EXPR and create access structures for all accesses to
   candidates for scalarization.  Return the created access or NULL if none is
   created.  */

static struct access *
build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
{
  struct access *ret = NULL;
  bool partial_ref;

  if (TREE_CODE (expr) == BIT_FIELD_REF
      || TREE_CODE (expr) == IMAGPART_EXPR
      || TREE_CODE (expr) == REALPART_EXPR)
    {
      expr = TREE_OPERAND (expr, 0);
      partial_ref = true;
    }
  else
    partial_ref = false;

  if (storage_order_barrier_p (expr))
    {
      disqualify_base_of_expr (expr, "storage order barrier.");
      return NULL;
    }

  /* We need to dive through V_C_Es in order to get the size of its parameter
     and not the result type.  Ada produces such statements.  We are also
     capable of handling the topmost V_C_E but not any of those buried in other
     handled components.  */
  if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
    expr = TREE_OPERAND (expr, 0);

  if (contains_view_convert_expr_p (expr))
    {
      disqualify_base_of_expr (expr, "V_C_E under a different handled "
			       "component.");
      return NULL;
    }
  if (TREE_THIS_VOLATILE (expr))
    {
      disqualify_base_of_expr (expr, "part of a volatile reference.");
      return NULL;
    }

  switch (TREE_CODE (expr))
    {
    case MEM_REF:
      if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
	  && sra_mode != SRA_MODE_EARLY_IPA)
	return NULL;
      /* fall through */
    case VAR_DECL:
    case PARM_DECL:
    case RESULT_DECL:
    case COMPONENT_REF:
    case ARRAY_REF:
    case ARRAY_RANGE_REF:
      ret = create_access (expr, stmt, write);
      break;

    default:
      break;
    }

  if (write && partial_ref && ret)
    ret->grp_partial_lhs = 1;

  return ret;
}

/* Scan expression EXPR and create access structures for all accesses to
   candidates for scalarization.  Return true if any access has been inserted.
   STMT must be the statement from which the expression is taken, WRITE must be
   true if the expression is a store and false otherwise. */

static bool
build_access_from_expr (tree expr, gimple *stmt, bool write)
{
  struct access *access;

  access = build_access_from_expr_1 (expr, stmt, write);
  if (access)
    {
      /* This means the aggregate is accesses as a whole in a way other than an
	 assign statement and thus cannot be removed even if we had a scalar
	 replacement for everything.  */
      if (cannot_scalarize_away_bitmap)
	bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
      return true;
    }
  return false;
}

/* Return the single non-EH successor edge of BB or NULL if there is none or
   more than one.  */

static edge
single_non_eh_succ (basic_block bb)
{
  edge e, res = NULL;
  edge_iterator ei;

  FOR_EACH_EDGE (e, ei, bb->succs)
    if (!(e->flags & EDGE_EH))
      {
	if (res)
	  return NULL;
	res = e;
      }

  return res;
}

/* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
   there is no alternative spot where to put statements SRA might need to
   generate after it.  The spot we are looking for is an edge leading to a
   single non-EH successor, if it exists and is indeed single.  RHS may be
   NULL, in that case ignore it.  */

static bool
disqualify_if_bad_bb_terminating_stmt (gimple *stmt, tree lhs, tree rhs)
{
  if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
      && stmt_ends_bb_p (stmt))
    {
      if (single_non_eh_succ (gimple_bb (stmt)))
	return false;

      disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
      if (rhs)
	disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
      return true;
    }
  return false;
}

/* Return true if the nature of BASE is such that it contains data even if
   there is no write to it in the function.  */

static bool
comes_initialized_p (tree base)
{
  return TREE_CODE (base) == PARM_DECL || constant_decl_p (base);
}

/* Scan expressions occurring in STMT, create access structures for all accesses
   to candidates for scalarization and remove those candidates which occur in
   statements or expressions that prevent them from being split apart.  Return
   true if any access has been inserted.  */

static bool
build_accesses_from_assign (gimple *stmt)
{
  tree lhs, rhs;
  struct access *lacc, *racc;

  if (!gimple_assign_single_p (stmt)
      /* Scope clobbers don't influence scalarization.  */
      || gimple_clobber_p (stmt))
    return false;

  lhs = gimple_assign_lhs (stmt);
  rhs = gimple_assign_rhs1 (stmt);

  if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
    return false;

  racc = build_access_from_expr_1 (rhs, stmt, false);
  lacc = build_access_from_expr_1 (lhs, stmt, true);

  if (lacc)
    {
      lacc->grp_assignment_write = 1;
      if (storage_order_barrier_p (rhs))
	lacc->grp_unscalarizable_region = 1;

      if (should_scalarize_away_bitmap && !is_gimple_reg_type (lacc->type))
	{
	  bool type_changing_p = false;
	  contains_vce_or_bfcref_p (lhs, &type_changing_p);
	  if (type_changing_p)
	    bitmap_set_bit (cannot_scalarize_away_bitmap,
			    DECL_UID (lacc->base));
	}
    }

  if (racc)
    {
      racc->grp_assignment_read = 1;
      if (should_scalarize_away_bitmap && !is_gimple_reg_type (racc->type))
	{
	  bool type_changing_p = false;
	  contains_vce_or_bfcref_p (rhs, &type_changing_p);

	  if (type_changing_p || gimple_has_volatile_ops (stmt))
	    bitmap_set_bit (cannot_scalarize_away_bitmap,
			    DECL_UID (racc->base));
	  else
	    bitmap_set_bit (should_scalarize_away_bitmap,
			    DECL_UID (racc->base));
	}
      if (storage_order_barrier_p (lhs))
	racc->grp_unscalarizable_region = 1;
    }

  if (lacc && racc
      && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
      && !lacc->grp_unscalarizable_region
      && !racc->grp_unscalarizable_region
      && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
      && lacc->size == racc->size
      && useless_type_conversion_p (lacc->type, racc->type))
    {
      struct assign_link *link;

      link = assign_link_pool.allocate ();
      memset (link, 0, sizeof (struct assign_link));

      link->lacc = lacc;
      link->racc = racc;
      add_link_to_rhs (racc, link);
      add_access_to_work_queue (racc);

      /* Let's delay marking the areas as written until propagation of accesses
	 across link, unless the nature of rhs tells us that its data comes
	 from elsewhere.  */
      if (!comes_initialized_p (racc->base))
	lacc->write = false;
    }

  return lacc || racc;
}

/* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
   GIMPLE_ASM operands with memory constrains which cannot be scalarized.  */

static bool
asm_visit_addr (gimple *, tree op, tree, void *)
{
  op = get_base_address (op);
  if (op
      && DECL_P (op))
    disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");

  return false;
}

/* Return true iff callsite CALL has at least as many actual arguments as there
   are formal parameters of the function currently processed by IPA-SRA and
   that their types match.  */

static inline bool
callsite_arguments_match_p (gimple *call)
{
  if (gimple_call_num_args (call) < (unsigned) func_param_count)
    return false;

  tree parm;
  int i;
  for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
       parm;
       parm = DECL_CHAIN (parm), i++)
    {
      tree arg = gimple_call_arg (call, i);
      if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
	return false;
    }
  return true;
}

/* Scan function and look for interesting expressions and create access
   structures for them.  Return true iff any access is created.  */

static bool
scan_function (void)
{
  basic_block bb;
  bool ret = false;

  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple_stmt_iterator gsi;
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);
	  tree t;
	  unsigned i;

	  if (final_bbs && stmt_can_throw_external (cfun, stmt))
	    bitmap_set_bit (final_bbs, bb->index);
	  switch (gimple_code (stmt))
	    {
	    case GIMPLE_RETURN:
	      t = gimple_return_retval (as_a <greturn *> (stmt));
	      if (t != NULL_TREE)
		ret |= build_access_from_expr (t, stmt, false);
	      if (final_bbs)
		bitmap_set_bit (final_bbs, bb->index);
	      break;

	    case GIMPLE_ASSIGN:
	      ret |= build_accesses_from_assign (stmt);
	      break;

	    case GIMPLE_CALL:
	      for (i = 0; i < gimple_call_num_args (stmt); i++)
		ret |= build_access_from_expr (gimple_call_arg (stmt, i),
					       stmt, false);

	      if (sra_mode == SRA_MODE_EARLY_IPA)
		{
		  tree dest = gimple_call_fndecl (stmt);
		  int flags = gimple_call_flags (stmt);

		  if (dest)
		    {
		      if (fndecl_built_in_p (dest, BUILT_IN_APPLY_ARGS))
			encountered_apply_args = true;
		      if (recursive_call_p (current_function_decl, dest))
			{
			  encountered_recursive_call = true;
			  if (!callsite_arguments_match_p (stmt))
			    encountered_unchangable_recursive_call = true;
			}
		    }

		  if (final_bbs
		      && (flags & (ECF_CONST | ECF_PURE)) == 0)
		    bitmap_set_bit (final_bbs, bb->index);
		}

	      t = gimple_call_lhs (stmt);
	      if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
		ret |= build_access_from_expr (t, stmt, true);
	      break;

	    case GIMPLE_ASM:
	      {
		gasm *asm_stmt = as_a <gasm *> (stmt);
		walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
					       asm_visit_addr);
		if (final_bbs)
		  bitmap_set_bit (final_bbs, bb->index);

		for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
		  {
		    t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
		    ret |= build_access_from_expr (t, asm_stmt, false);
		  }
		for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
		  {
		    t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
		    ret |= build_access_from_expr (t, asm_stmt, true);
		  }
	      }
	      break;

	    default:
	      break;
	    }
	}
    }

  return ret;
}

/* Helper of QSORT function. There are pointers to accesses in the array.  An
   access is considered smaller than another if it has smaller offset or if the
   offsets are the same but is size is bigger. */

static int
compare_access_positions (const void *a, const void *b)
{
  const access_p *fp1 = (const access_p *) a;
  const access_p *fp2 = (const access_p *) b;
  const access_p f1 = *fp1;
  const access_p f2 = *fp2;

  if (f1->offset != f2->offset)
    return f1->offset < f2->offset ? -1 : 1;

  if (f1->size == f2->size)
    {
      if (f1->type == f2->type)
	return 0;
      /* Put any non-aggregate type before any aggregate type.  */
      else if (!is_gimple_reg_type (f1->type)
	  && is_gimple_reg_type (f2->type))
	return 1;
      else if (is_gimple_reg_type (f1->type)
	       && !is_gimple_reg_type (f2->type))
	return -1;
      /* Put any complex or vector type before any other scalar type.  */
      else if (TREE_CODE (f1->type) != COMPLEX_TYPE
	       && TREE_CODE (f1->type) != VECTOR_TYPE
	       && (TREE_CODE (f2->type) == COMPLEX_TYPE
		   || TREE_CODE (f2->type) == VECTOR_TYPE))
	return 1;
      else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
		|| TREE_CODE (f1->type) == VECTOR_TYPE)
	       && TREE_CODE (f2->type) != COMPLEX_TYPE
	       && TREE_CODE (f2->type) != VECTOR_TYPE)
	return -1;
      /* Put any integral type before any non-integral type.  When splicing, we
	 make sure that those with insufficient precision and occupying the
	 same space are not scalarized.  */
      else if (INTEGRAL_TYPE_P (f1->type)
	       && !INTEGRAL_TYPE_P (f2->type))
	return -1;
      else if (!INTEGRAL_TYPE_P (f1->type)
	       && INTEGRAL_TYPE_P (f2->type))
	return 1;
      /* Put the integral type with the bigger precision first.  */
      else if (INTEGRAL_TYPE_P (f1->type)
	       && INTEGRAL_TYPE_P (f2->type)
	       && (TYPE_PRECISION (f2->type) != TYPE_PRECISION (f1->type)))
	return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
      /* Stabilize the sort.  */
      return TYPE_UID (f1->type) - TYPE_UID (f2->type);
    }

  /* We want the bigger accesses first, thus the opposite operator in the next
     line: */
  return f1->size > f2->size ? -1 : 1;
}


/* Append a name of the declaration to the name obstack.  A helper function for
   make_fancy_name.  */

static void
make_fancy_decl_name (tree decl)
{
  char buffer[32];

  tree name = DECL_NAME (decl);
  if (name)
    obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
		  IDENTIFIER_LENGTH (name));
  else
    {
      sprintf (buffer, "D%u", DECL_UID (decl));
      obstack_grow (&name_obstack, buffer, strlen (buffer));
    }
}

/* Helper for make_fancy_name.  */

static void
make_fancy_name_1 (tree expr)
{
  char buffer[32];
  tree index;

  if (DECL_P (expr))
    {
      make_fancy_decl_name (expr);
      return;
    }

  switch (TREE_CODE (expr))
    {
    case COMPONENT_REF:
      make_fancy_name_1 (TREE_OPERAND (expr, 0));
      obstack_1grow (&name_obstack, '$');
      make_fancy_decl_name (TREE_OPERAND (expr, 1));
      break;

    case ARRAY_REF:
      make_fancy_name_1 (TREE_OPERAND (expr, 0));
      obstack_1grow (&name_obstack, '$');
      /* Arrays with only one element may not have a constant as their
	 index. */
      index = TREE_OPERAND (expr, 1);
      if (TREE_CODE (index) != INTEGER_CST)
	break;
      sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
      obstack_grow (&name_obstack, buffer, strlen (buffer));
      break;

    case ADDR_EXPR:
      make_fancy_name_1 (TREE_OPERAND (expr, 0));
      break;

    case MEM_REF:
      make_fancy_name_1 (TREE_OPERAND (expr, 0));
      if (!integer_zerop (TREE_OPERAND (expr, 1)))
	{
	  obstack_1grow (&name_obstack, '$');
	  sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
		   TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
	  obstack_grow (&name_obstack, buffer, strlen (buffer));
	}
      break;

    case BIT_FIELD_REF:
    case REALPART_EXPR:
    case IMAGPART_EXPR:
      gcc_unreachable (); 	/* we treat these as scalars.  */
      break;
    default:
      break;
    }
}

/* Create a human readable name for replacement variable of ACCESS.  */

static char *
make_fancy_name (tree expr)
{
  make_fancy_name_1 (expr);
  obstack_1grow (&name_obstack, '\0');
  return XOBFINISH (&name_obstack, char *);
}

/* Construct a MEM_REF that would reference a part of aggregate BASE of type
   EXP_TYPE at the given OFFSET and with storage order REVERSE.  If BASE is
   something for which get_addr_base_and_unit_offset returns NULL, gsi must
   be non-NULL and is used to insert new statements either before or below
   the current one as specified by INSERT_AFTER.  This function is not capable
   of handling bitfields.  */

tree
build_ref_for_offset (location_t loc, tree base, poly_int64 offset,
		      bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
		      bool insert_after)
{
  tree prev_base = base;
  tree off;
  tree mem_ref;
  poly_int64 base_offset;
  unsigned HOST_WIDE_INT misalign;
  unsigned int align;

  /* Preserve address-space information.  */
  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
  if (as != TYPE_ADDR_SPACE (exp_type))
    exp_type = build_qualified_type (exp_type,
				     TYPE_QUALS (exp_type)
				     | ENCODE_QUAL_ADDR_SPACE (as));

  poly_int64 byte_offset = exact_div (offset, BITS_PER_UNIT);
  get_object_alignment_1 (base, &align, &misalign);
  base = get_addr_base_and_unit_offset (base, &base_offset);

  /* get_addr_base_and_unit_offset returns NULL for references with a variable
     offset such as array[var_index].  */
  if (!base)
    {
      gassign *stmt;
      tree tmp, addr;

      gcc_checking_assert (gsi);
      tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)));
      addr = build_fold_addr_expr (unshare_expr (prev_base));
      STRIP_USELESS_TYPE_CONVERSION (addr);
      stmt = gimple_build_assign (tmp, addr);
      gimple_set_location (stmt, loc);
      if (insert_after)
	gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
      else
	gsi_insert_before (gsi, stmt, GSI_SAME_STMT);

      off = build_int_cst (reference_alias_ptr_type (prev_base), byte_offset);
      base = tmp;
    }
  else if (TREE_CODE (base) == MEM_REF)
    {
      off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
			   base_offset + byte_offset);
      off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
      base = unshare_expr (TREE_OPERAND (base, 0));
    }
  else
    {
      off = build_int_cst (reference_alias_ptr_type (prev_base),
			   base_offset + byte_offset);
      base = build_fold_addr_expr (unshare_expr (base));
    }

  unsigned int align_bound = known_alignment (misalign + offset);
  if (align_bound != 0)
    align = MIN (align, align_bound);
  if (align != TYPE_ALIGN (exp_type))
    exp_type = build_aligned_type (exp_type, align);

  mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
  REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse;
  if (TREE_THIS_VOLATILE (prev_base))
    TREE_THIS_VOLATILE (mem_ref) = 1;
  if (TREE_SIDE_EFFECTS (prev_base))
    TREE_SIDE_EFFECTS (mem_ref) = 1;
  return mem_ref;
}

/* Construct a memory reference to a part of an aggregate BASE at the given
   OFFSET and of the same type as MODEL.  In case this is a reference to a
   bit-field, the function will replicate the last component_ref of model's
   expr to access it.  GSI and INSERT_AFTER have the same meaning as in
   build_ref_for_offset.  */

static tree
build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
		     struct access *model, gimple_stmt_iterator *gsi,
		     bool insert_after)
{
  if (TREE_CODE (model->expr) == COMPONENT_REF
      && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
    {
      /* This access represents a bit-field.  */
      tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);

      offset -= int_bit_position (fld);
      exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
      t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type,
				gsi, insert_after);
      /* The flag will be set on the record type.  */
      REF_REVERSE_STORAGE_ORDER (t) = 0;
      return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
			      NULL_TREE);
    }
  else
    return
      build_ref_for_offset (loc, base, offset, model->reverse, model->type,
			    gsi, insert_after);
}

/* Attempt to build a memory reference that we could but into a gimple
   debug_bind statement.  Similar to build_ref_for_model but punts if it has to
   create statements and return s NULL instead.  This function also ignores
   alignment issues and so its results should never end up in non-debug
   statements.  */

static tree
build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
			   struct access *model)
{
  poly_int64 base_offset;
  tree off;

  if (TREE_CODE (model->expr) == COMPONENT_REF
      && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
    return NULL_TREE;

  base = get_addr_base_and_unit_offset (base, &base_offset);
  if (!base)
    return NULL_TREE;
  if (TREE_CODE (base) == MEM_REF)
    {
      off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
			   base_offset + offset / BITS_PER_UNIT);
      off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
      base = unshare_expr (TREE_OPERAND (base, 0));
    }
  else
    {
      off = build_int_cst (reference_alias_ptr_type (base),
			   base_offset + offset / BITS_PER_UNIT);
      base = build_fold_addr_expr (unshare_expr (base));
    }

  return fold_build2_loc (loc, MEM_REF, model->type, base, off);
}

/* Construct a memory reference consisting of component_refs and array_refs to
   a part of an aggregate *RES (which is of type TYPE).  The requested part
   should have type EXP_TYPE at be the given OFFSET.  This function might not
   succeed, it returns true when it does and only then *RES points to something
   meaningful.  This function should be used only to build expressions that we
   might need to present to user (e.g. in warnings).  In all other situations,
   build_ref_for_model or build_ref_for_offset should be used instead.  */

static bool
build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
				    tree exp_type)
{
  while (1)
    {
      tree fld;
      tree tr_size, index, minidx;
      HOST_WIDE_INT el_size;

      if (offset == 0 && exp_type
	  && types_compatible_p (exp_type, type))
	return true;

      switch (TREE_CODE (type))
	{
	case UNION_TYPE:
	case QUAL_UNION_TYPE:
	case RECORD_TYPE:
	  for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
	    {
	      HOST_WIDE_INT pos, size;
	      tree tr_pos, expr, *expr_ptr;

	      if (TREE_CODE (fld) != FIELD_DECL)
		continue;

	      tr_pos = bit_position (fld);
	      if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
		continue;
	      pos = tree_to_uhwi (tr_pos);
	      gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
	      tr_size = DECL_SIZE (fld);
	      if (!tr_size || !tree_fits_uhwi_p (tr_size))
		continue;
	      size = tree_to_uhwi (tr_size);
	      if (size == 0)
		{
		  if (pos != offset)
		    continue;
		}
	      else if (pos > offset || (pos + size) <= offset)
		continue;

	      expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
			     NULL_TREE);
	      expr_ptr = &expr;
	      if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
						      offset - pos, exp_type))
		{
		  *res = expr;
		  return true;
		}
	    }
	  return false;

	case ARRAY_TYPE:
	  tr_size = TYPE_SIZE (TREE_TYPE (type));
	  if (!tr_size || !tree_fits_uhwi_p (tr_size))
	    return false;
	  el_size = tree_to_uhwi (tr_size);

	  minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
	  if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
	    return false;
	  index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
	  if (!integer_zerop (minidx))
	    index = int_const_binop (PLUS_EXPR, index, minidx);
	  *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
			 NULL_TREE, NULL_TREE);
	  offset = offset % el_size;
	  type = TREE_TYPE (type);
	  break;

	default:
	  if (offset != 0)
	    return false;

	  if (exp_type)
	    return false;
	  else
	    return true;
	}
    }
}

/* Return true iff TYPE is stdarg va_list type.  */

static inline bool
is_va_list_type (tree type)
{
  return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
}

/* Print message to dump file why a variable was rejected. */

static void
reject (tree var, const char *msg)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
      print_generic_expr (dump_file, var);
      fprintf (dump_file, "\n");
    }
}

/* Return true if VAR is a candidate for SRA.  */

static bool
maybe_add_sra_candidate (tree var)
{
  tree type = TREE_TYPE (var);
  const char *msg;
  tree_node **slot;

  if (!AGGREGATE_TYPE_P (type)) 
    {
      reject (var, "not aggregate");
      return false;
    }
  /* Allow constant-pool entries (that "need to live in memory")
     unless we are doing IPA SRA.  */
  if (needs_to_live_in_memory (var)
      && (sra_mode == SRA_MODE_EARLY_IPA || !constant_decl_p (var)))
    {
      reject (var, "needs to live in memory");
      return false;
    }
  if (TREE_THIS_VOLATILE (var))
    {
      reject (var, "is volatile");
      return false;
    }
  if (!COMPLETE_TYPE_P (type))
    {
      reject (var, "has incomplete type");
      return false;
    }
  if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
    {
      reject (var, "type size not fixed");
      return false;
    }
  if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
    {
      reject (var, "type size is zero");
      return false;
    }
  if (type_internals_preclude_sra_p (type, &msg))
    {
      reject (var, msg);
      return false;
    }
  if (/* Fix for PR 41089.  tree-stdarg.c needs to have va_lists intact but
	 we also want to schedule it rather late.  Thus we ignore it in
	 the early pass. */
      (sra_mode == SRA_MODE_EARLY_INTRA
       && is_va_list_type (type)))
    {
      reject (var, "is va_list");
      return false;
    }

  bitmap_set_bit (candidate_bitmap, DECL_UID (var));
  slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
  *slot = var;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
      print_generic_expr (dump_file, var);
      fprintf (dump_file, "\n");
    }

  return true;
}

/* The very first phase of intraprocedural SRA.  It marks in candidate_bitmap
   those with type which is suitable for scalarization.  */

static bool
find_var_candidates (void)
{
  tree var, parm;
  unsigned int i;
  bool ret = false;

  for (parm = DECL_ARGUMENTS (current_function_decl);
       parm;
       parm = DECL_CHAIN (parm))
    ret |= maybe_add_sra_candidate (parm);

  FOR_EACH_LOCAL_DECL (cfun, i, var)
    {
      if (!VAR_P (var))
        continue;

      ret |= maybe_add_sra_candidate (var);
    }

  return ret;
}

/* Sort all accesses for the given variable, check for partial overlaps and
   return NULL if there are any.  If there are none, pick a representative for
   each combination of offset and size and create a linked list out of them.
   Return the pointer to the first representative and make sure it is the first
   one in the vector of accesses.  */

static struct access *
sort_and_splice_var_accesses (tree var)
{
  int i, j, access_count;
  struct access *res, **prev_acc_ptr = &res;
  vec<access_p> *access_vec;
  bool first = true;
  HOST_WIDE_INT low = -1, high = 0;

  access_vec = get_base_access_vector (var);
  if (!access_vec)
    return NULL;
  access_count = access_vec->length ();

  /* Sort by <OFFSET, SIZE>.  */
  access_vec->qsort (compare_access_positions);

  i = 0;
  while (i < access_count)
    {
      struct access *access = (*access_vec)[i];
      bool grp_write = access->write;
      bool grp_read = !access->write;
      bool grp_scalar_write = access->write
	&& is_gimple_reg_type (access->type);
      bool grp_scalar_read = !access->write
	&& is_gimple_reg_type (access->type);
      bool grp_assignment_read = access->grp_assignment_read;
      bool grp_assignment_write = access->grp_assignment_write;
      bool multiple_scalar_reads = false;
      bool total_scalarization = access->grp_total_scalarization;
      bool grp_partial_lhs = access->grp_partial_lhs;
      bool first_scalar = is_gimple_reg_type (access->type);
      bool unscalarizable_region = access->grp_unscalarizable_region;
      bool bf_non_full_precision
	= (INTEGRAL_TYPE_P (access->type)
	   && TYPE_PRECISION (access->type) != access->size
	   && TREE_CODE (access->expr) == COMPONENT_REF
	   && DECL_BIT_FIELD (TREE_OPERAND (access->expr, 1)));

      if (first || access->offset >= high)
	{
	  first = false;
	  low = access->offset;
	  high = access->offset + access->size;
	}
      else if (access->offset > low && access->offset + access->size > high)
	return NULL;
      else
	gcc_assert (access->offset >= low
		    && access->offset + access->size <= high);

      j = i + 1;
      while (j < access_count)
	{
	  struct access *ac2 = (*access_vec)[j];
	  if (ac2->offset != access->offset || ac2->size != access->size)
	    break;
	  if (ac2->write)
	    {
	      grp_write = true;
	      grp_scalar_write = (grp_scalar_write
				  || is_gimple_reg_type (ac2->type));
	    }
	  else
	    {
	      grp_read = true;
	      if (is_gimple_reg_type (ac2->type))
		{
		  if (grp_scalar_read)
		    multiple_scalar_reads = true;
		  else
		    grp_scalar_read = true;
		}
	    }
	  grp_assignment_read |= ac2->grp_assignment_read;
	  grp_assignment_write |= ac2->grp_assignment_write;
	  grp_partial_lhs |= ac2->grp_partial_lhs;
	  unscalarizable_region |= ac2->grp_unscalarizable_region;
	  total_scalarization |= ac2->grp_total_scalarization;
	  relink_to_new_repr (access, ac2);

	  /* If there are both aggregate-type and scalar-type accesses with
	     this combination of size and offset, the comparison function
	     should have put the scalars first.  */
	  gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
	  /* It also prefers integral types to non-integral.  However, when the
	     precision of the selected type does not span the entire area and
	     should also be used for a non-integer (i.e. float), we must not
	     let that happen.  Normally analyze_access_subtree expands the type
	     to cover the entire area but for bit-fields it doesn't.  */
	  if (bf_non_full_precision && !INTEGRAL_TYPE_P (ac2->type))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  fprintf (dump_file, "Cannot scalarize the following access "
			   "because insufficient precision integer type was "
			   "selected.\n  ");
		  dump_access (dump_file, access, false);
		}
	      unscalarizable_region = true;
	    }
	  ac2->group_representative = access;
	  j++;
	}

      i = j;

      access->group_representative = access;
      access->grp_write = grp_write;
      access->grp_read = grp_read;
      access->grp_scalar_read = grp_scalar_read;
      access->grp_scalar_write = grp_scalar_write;
      access->grp_assignment_read = grp_assignment_read;
      access->grp_assignment_write = grp_assignment_write;
      access->grp_hint = total_scalarization
	|| (multiple_scalar_reads && !constant_decl_p (var));
      access->grp_total_scalarization = total_scalarization;
      access->grp_partial_lhs = grp_partial_lhs;
      access->grp_unscalarizable_region = unscalarizable_region;

      *prev_acc_ptr = access;
      prev_acc_ptr = &access->next_grp;
    }

  gcc_assert (res == (*access_vec)[0]);
  return res;
}

/* Create a variable for the given ACCESS which determines the type, name and a
   few other properties.  Return the variable declaration and store it also to
   ACCESS->replacement.  REG_TREE is used when creating a declaration to base a
   default-definition SSA name on on in order to facilitate an uninitialized
   warning.  It is used instead of the actual ACCESS type if that is not of a
   gimple register type.  */

static tree
create_access_replacement (struct access *access, tree reg_type = NULL_TREE)
{
  tree repl;

  tree type = access->type;
  if (reg_type && !is_gimple_reg_type (type))
    type = reg_type;

  if (access->grp_to_be_debug_replaced)
    {
      repl = create_tmp_var_raw (access->type);
      DECL_CONTEXT (repl) = current_function_decl;
    }
  else
    /* Drop any special alignment on the type if it's not on the main
       variant.  This avoids issues with weirdo ABIs like AAPCS.  */
    repl = create_tmp_var (build_qualified_type (TYPE_MAIN_VARIANT (type),
						 TYPE_QUALS (type)), "SR");
  if (TREE_CODE (type) == COMPLEX_TYPE
      || TREE_CODE (type) == VECTOR_TYPE)
    {
      if (!access->grp_partial_lhs)
	DECL_GIMPLE_REG_P (repl) = 1;
    }
  else if (access->grp_partial_lhs
	   && is_gimple_reg_type (type))
    TREE_ADDRESSABLE (repl) = 1;

  DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
  DECL_ARTIFICIAL (repl) = 1;
  DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);

  if (DECL_NAME (access->base)
      && !DECL_IGNORED_P (access->base)
      && !DECL_ARTIFICIAL (access->base))
    {
      char *pretty_name = make_fancy_name (access->expr);
      tree debug_expr = unshare_expr_without_location (access->expr), d;
      bool fail = false;

      DECL_NAME (repl) = get_identifier (pretty_name);
      DECL_NAMELESS (repl) = 1;
      obstack_free (&name_obstack, pretty_name);

      /* Get rid of any SSA_NAMEs embedded in debug_expr,
	 as DECL_DEBUG_EXPR isn't considered when looking for still
	 used SSA_NAMEs and thus they could be freed.  All debug info
	 generation cares is whether something is constant or variable
	 and that get_ref_base_and_extent works properly on the
	 expression.  It cannot handle accesses at a non-constant offset
	 though, so just give up in those cases.  */
      for (d = debug_expr;
	   !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
	   d = TREE_OPERAND (d, 0))
	switch (TREE_CODE (d))
	  {
	  case ARRAY_REF:
	  case ARRAY_RANGE_REF:
	    if (TREE_OPERAND (d, 1)
		&& TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
	      fail = true;
	    if (TREE_OPERAND (d, 3)
		&& TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
	      fail = true;
	    /* FALLTHRU */
	  case COMPONENT_REF:
	    if (TREE_OPERAND (d, 2)
		&& TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
	      fail = true;
	    break;
	  case MEM_REF:
	    if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
	      fail = true;
	    else
	      d = TREE_OPERAND (d, 0);
	    break;
	  default:
	    break;
	  }
      if (!fail)
	{
	  SET_DECL_DEBUG_EXPR (repl, debug_expr);
	  DECL_HAS_DEBUG_EXPR_P (repl) = 1;
	}
      if (access->grp_no_warning)
	TREE_NO_WARNING (repl) = 1;
      else
	TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
    }
  else
    TREE_NO_WARNING (repl) = 1;

  if (dump_file)
    {
      if (access->grp_to_be_debug_replaced)
	{
	  fprintf (dump_file, "Created a debug-only replacement for ");
	  print_generic_expr (dump_file, access->base);
	  fprintf (dump_file, " offset: %u, size: %u\n",
		   (unsigned) access->offset, (unsigned) access->size);
	}
      else
	{
	  fprintf (dump_file, "Created a replacement for ");
	  print_generic_expr (dump_file, access->base);
	  fprintf (dump_file, " offset: %u, size: %u: ",
		   (unsigned) access->offset, (unsigned) access->size);
	  print_generic_expr (dump_file, repl);
	  fprintf (dump_file, "\n");
	}
    }
  sra_stats.replacements++;

  return repl;
}

/* Return ACCESS scalar replacement, which must exist.  */

static inline tree
get_access_replacement (struct access *access)
{
  gcc_checking_assert (access->replacement_decl);
  return access->replacement_decl;
}


/* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
   linked list along the way.  Stop when *ACCESS is NULL or the access pointed
   to it is not "within" the root.  Return false iff some accesses partially
   overlap.  */

static bool
build_access_subtree (struct access **access)
{
  struct access *root = *access, *last_child = NULL;
  HOST_WIDE_INT limit = root->offset + root->size;

  *access = (*access)->next_grp;
  while  (*access && (*access)->offset + (*access)->size <= limit)
    {
      if (!last_child)
	root->first_child = *access;
      else
	last_child->next_sibling = *access;
      last_child = *access;
      (*access)->parent = root;
      (*access)->grp_write |= root->grp_write;

      if (!build_access_subtree (access))
	return false;
    }

  if (*access && (*access)->offset < limit)
    return false;

  return true;
}

/* Build a tree of access representatives, ACCESS is the pointer to the first
   one, others are linked in a list by the next_grp field.  Return false iff
   some accesses partially overlap.  */

static bool
build_access_trees (struct access *access)
{
  while (access)
    {
      struct access *root = access;

      if (!build_access_subtree (&access))
	return false;
      root->next_grp = access;
    }
  return true;
}

/* Return true if expr contains some ARRAY_REFs into a variable bounded
   array.  */

static bool
expr_with_var_bounded_array_refs_p (tree expr)
{
  while (handled_component_p (expr))
    {
      if (TREE_CODE (expr) == ARRAY_REF
	  && !tree_fits_shwi_p (array_ref_low_bound (expr)))
	return true;
      expr = TREE_OPERAND (expr, 0);
    }
  return false;
}

/* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
   both seeming beneficial and when ALLOW_REPLACEMENTS allows it.  Also set all
   sorts of access flags appropriately along the way, notably always set
   grp_read and grp_assign_read according to MARK_READ and grp_write when
   MARK_WRITE is true.

   Creating a replacement for a scalar access is considered beneficial if its
   grp_hint is set (this means we are either attempting total scalarization or
   there is more than one direct read access) or according to the following
   table:

   Access written to through a scalar type (once or more times)
   |
   |	Written to in an assignment statement
   |	|
   |	|	Access read as scalar _once_
   |	|	|
   |   	|	|	Read in an assignment statement
   |	|	|	|
   |   	|	|	|	Scalarize	Comment
-----------------------------------------------------------------------------
   0	0	0	0			No access for the scalar
   0	0	0	1			No access for the scalar
   0	0	1	0	No		Single read - won't help
   0	0	1	1	No		The same case
   0	1	0	0			No access for the scalar
   0	1	0	1			No access for the scalar
   0	1	1	0	Yes		s = *g; return s.i;
   0	1	1	1       Yes		The same case as above
   1	0	0	0	No		Won't help
   1	0	0	1	Yes		s.i = 1; *g = s;
   1	0	1	0	Yes		s.i = 5; g = s.i;
   1	0	1	1	Yes		The same case as above
   1	1	0	0	No		Won't help.
   1	1	0	1	Yes		s.i = 1; *g = s;
   1	1	1	0	Yes		s = *g; return s.i;
   1	1	1	1	Yes		Any of the above yeses  */

static bool
analyze_access_subtree (struct access *root, struct access *parent,
			bool allow_replacements)
{
  struct access *child;
  HOST_WIDE_INT limit = root->offset + root->size;
  HOST_WIDE_INT covered_to = root->offset;
  bool scalar = is_gimple_reg_type (root->type);
  bool hole = false, sth_created = false;

  if (parent)
    {
      if (parent->grp_read)
	root->grp_read = 1;
      if (parent->grp_assignment_read)
	root->grp_assignment_read = 1;
      if (parent->grp_write)
	root->grp_write = 1;
      if (parent->grp_assignment_write)
	root->grp_assignment_write = 1;
      if (parent->grp_total_scalarization)
	root->grp_total_scalarization = 1;
    }

  if (root->grp_unscalarizable_region)
    allow_replacements = false;

  if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
    allow_replacements = false;

  for (child = root->first_child; child; child = child->next_sibling)
    {
      hole |= covered_to < child->offset;
      sth_created |= analyze_access_subtree (child, root,
					     allow_replacements && !scalar);

      root->grp_unscalarized_data |= child->grp_unscalarized_data;
      root->grp_total_scalarization &= child->grp_total_scalarization;
      if (child->grp_covered)
	covered_to += child->size;
      else
	hole = true;
    }

  if (allow_replacements && scalar && !root->first_child
      && (root->grp_hint
	  || ((root->grp_scalar_read || root->grp_assignment_read)
	      && (root->grp_scalar_write || root->grp_assignment_write))))
    {
      /* Always create access replacements that cover the whole access.
         For integral types this means the precision has to match.
	 Avoid assumptions based on the integral type kind, too.  */
      if (INTEGRAL_TYPE_P (root->type)
	  && (TREE_CODE (root->type) != INTEGER_TYPE
	      || TYPE_PRECISION (root->type) != root->size)
	  /* But leave bitfield accesses alone.  */
	  && (TREE_CODE (root->expr) != COMPONENT_REF
	      || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
	{
	  tree rt = root->type;
	  gcc_assert ((root->offset % BITS_PER_UNIT) == 0
		      && (root->size % BITS_PER_UNIT) == 0);
	  root->type = build_nonstandard_integer_type (root->size,
						       TYPE_UNSIGNED (rt));
	  root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base,
					     root->offset, root->reverse,
					     root->type, NULL, false);

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Changing the type of a replacement for ");
	      print_generic_expr (dump_file, root->base);
	      fprintf (dump_file, " offset: %u, size: %u ",
		       (unsigned) root->offset, (unsigned) root->size);
	      fprintf (dump_file, " to an integer.\n");
	    }
	}

      root->grp_to_be_replaced = 1;
      root->replacement_decl = create_access_replacement (root);
      sth_created = true;
      hole = false;
    }
  else
    {
      if (allow_replacements
	  && scalar && !root->first_child
	  && (root->grp_scalar_write || root->grp_assignment_write)
	  && !bitmap_bit_p (cannot_scalarize_away_bitmap,
			    DECL_UID (root->base)))
	{
	  gcc_checking_assert (!root->grp_scalar_read
			       && !root->grp_assignment_read);
	  sth_created = true;
	  if (MAY_HAVE_DEBUG_BIND_STMTS)
	    {
	      root->grp_to_be_debug_replaced = 1;
	      root->replacement_decl = create_access_replacement (root);
	    }
	}

      if (covered_to < limit)
	hole = true;
      if (scalar || !allow_replacements)
	root->grp_total_scalarization = 0;
    }

  if (!hole || root->grp_total_scalarization)
    root->grp_covered = 1;
  else if (root->grp_write || comes_initialized_p (root->base))
    root->grp_unscalarized_data = 1; /* not covered and written to */
  return sth_created;
}

/* Analyze all access trees linked by next_grp by the means of
   analyze_access_subtree.  */
static bool
analyze_access_trees (struct access *access)
{
  bool ret = false;

  while (access)
    {
      if (analyze_access_subtree (access, NULL, true))
	ret = true;
      access = access->next_grp;
    }

  return ret;
}

/* Return true iff a potential new child of LACC at offset OFFSET and with size
   SIZE would conflict with an already existing one.  If exactly such a child
   already exists in LACC, store a pointer to it in EXACT_MATCH.  */

static bool
child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
			      HOST_WIDE_INT size, struct access **exact_match)
{
  struct access *child;

  for (child = lacc->first_child; child; child = child->next_sibling)
    {
      if (child->offset == norm_offset && child->size == size)
	{
	  *exact_match = child;
	  return true;
	}

      if (child->offset < norm_offset + size
	  && child->offset + child->size > norm_offset)
	return true;
    }

  return false;
}

/* Create a new child access of PARENT, with all properties just like MODEL
   except for its offset and with its grp_write false and grp_read true.
   Return the new access or NULL if it cannot be created.  Note that this
   access is created long after all splicing and sorting, it's not located in
   any access vector and is automatically a representative of its group.  Set
   the gpr_write flag of the new accesss if SET_GRP_WRITE is true.  */

static struct access *
create_artificial_child_access (struct access *parent, struct access *model,
				HOST_WIDE_INT new_offset,
				bool set_grp_write)
{
  struct access **child;
  tree expr = parent->base;

  gcc_assert (!model->grp_unscalarizable_region);

  struct access *access = access_pool.allocate ();
  memset (access, 0, sizeof (struct access));
  if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
					   model->type))
    {
      access->grp_no_warning = true;
      expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
				  new_offset, model, NULL, false);
    }

  access->base = parent->base;
  access->expr = expr;
  access->offset = new_offset;
  access->size = model->size;
  access->type = model->type;
  access->grp_write = set_grp_write;
  access->grp_read = false;
  access->reverse = model->reverse;

  child = &parent->first_child;
  while (*child && (*child)->offset < new_offset)
    child = &(*child)->next_sibling;

  access->next_sibling = *child;
  *child = access;

  return access;
}


/* Beginning with ACCESS, traverse its whole access subtree and mark all
   sub-trees as written to.  If any of them has not been marked so previously
   and has assignment links leading from it, re-enqueue it.  */

static void
subtree_mark_written_and_enqueue (struct access *access)
{
  if (access->grp_write)
    return;
  access->grp_write = true;
  add_access_to_work_queue (access);

  struct access *child;
  for (child = access->first_child; child; child = child->next_sibling)
    subtree_mark_written_and_enqueue (child);
}

/* If there is still budget to create a propagation access for DECL, return
   true and decrement the budget.  Otherwise return false.  */

static bool
budget_for_propagation_access (tree decl)
{
  unsigned b, *p = propagation_budget->get (decl);
  if (p)
    b = *p;
  else
    b = PARAM_SRA_MAX_PROPAGATIONS;

  if (b == 0)
    return false;
  b--;

  if (b == 0 && dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "The propagation budget of ");
      print_generic_expr (dump_file, decl);
      fprintf (dump_file, " (UID: %u) has been exhausted.\n", DECL_UID (decl));
    }
  propagation_budget->put (decl, b);
  return true;
}

/* Propagate subaccesses and grp_write flags of RACC across an assignment link
   to LACC.  Enqueue sub-accesses as necessary so that the write flag is
   propagated transitively.  Return true if anything changed.  Additionally, if
   RACC is a scalar access but LACC is not, change the type of the latter, if
   possible.  */

static bool
propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
{
  struct access *rchild;
  HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
  bool ret = false;

  /* IF the LHS is still not marked as being written to, we only need to do so
     if the RHS at this level actually was.  */
  if (!lacc->grp_write)
    {
      gcc_checking_assert (!comes_initialized_p (racc->base));
      if (racc->grp_write)
	{
	  subtree_mark_written_and_enqueue (lacc);
	  ret = true;
	}
    }

  if (is_gimple_reg_type (lacc->type)
      || lacc->grp_unscalarizable_region
      || racc->grp_unscalarizable_region)
    {
      if (!lacc->grp_write)
	{
	  ret = true;
	  subtree_mark_written_and_enqueue (lacc);
	}
      return ret;
    }

  if (is_gimple_reg_type (racc->type))
    {
      if (!lacc->grp_write)
	{
	  ret = true;
	  subtree_mark_written_and_enqueue (lacc);
	}
      if (!lacc->first_child && !racc->first_child)
	{
	  tree t = lacc->base;

	  lacc->type = racc->type;
	  if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
						  lacc->offset, racc->type))
	    lacc->expr = t;
	  else
	    {
	      lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
						lacc->base, lacc->offset,
						racc, NULL, false);
	      lacc->grp_no_warning = true;
	    }
	}
      return ret;
    }

  for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
    {
      struct access *new_acc = NULL;
      HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;

      if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
					&new_acc))
	{
	  if (new_acc)
	    {
	      if (!new_acc->grp_write && rchild->grp_write)
		{
		  gcc_assert (!lacc->grp_write);
		  subtree_mark_written_and_enqueue (new_acc);
		  ret = true;
		}

	      rchild->grp_hint = 1;
	      new_acc->grp_hint |= new_acc->grp_read;
	      if (rchild->first_child
		  && propagate_subaccesses_across_link (new_acc, rchild))
		{
		  ret = 1;
		  add_access_to_work_queue (new_acc);
		}
	    }
	  else
	    {
	      if (!lacc->grp_write)
		{
		  ret = true;
		  subtree_mark_written_and_enqueue (lacc);
		}
	    }
	  continue;
	}

      if (rchild->grp_unscalarizable_region
	  || !budget_for_propagation_access (lacc->base))
	{
	  if (rchild->grp_write && !lacc->grp_write)
	    {
	      ret = true;
	      subtree_mark_written_and_enqueue (lacc);
	    }
	  continue;
	}

      rchild->grp_hint = 1;
      new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
						lacc->grp_write
						|| rchild->grp_write);
      gcc_checking_assert (new_acc);
      if (racc->first_child)
	propagate_subaccesses_across_link (new_acc, rchild);

      add_access_to_work_queue (lacc);
      ret = true;
    }

  return ret;
}

/* Propagate all subaccesses across assignment links.  */

static void
propagate_all_subaccesses (void)
{
  propagation_budget = new hash_map<tree, unsigned>;
  while (work_queue_head)
    {
      struct access *racc = pop_access_from_work_queue ();
      struct assign_link *link;

      if (racc->group_representative)
	racc= racc->group_representative;
      gcc_assert (racc->first_link);

      for (link = racc->first_link; link; link = link->next)
	{
	  struct access *lacc = link->lacc;

	  if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
	    continue;
	  lacc = lacc->group_representative;

	  bool reque_parents = false;
	  if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base)))
	    {
	      if (!lacc->grp_write)
		{
		  subtree_mark_written_and_enqueue (lacc);
		  reque_parents = true;
		}
	    }
	  else if (propagate_subaccesses_across_link (lacc, racc))
	    reque_parents = true;

	  if (reque_parents)
	    do
	      {
		add_access_to_work_queue (lacc);
		lacc = lacc->parent;
	      }
	    while (lacc);
	}
    }
  delete propagation_budget;
}

/* Go through all accesses collected throughout the (intraprocedural) analysis
   stage, exclude overlapping ones, identify representatives and build trees
   out of them, making decisions about scalarization on the way.  Return true
   iff there are any to-be-scalarized variables after this stage. */

static bool
analyze_all_variable_accesses (void)
{
  int res = 0;
  bitmap tmp = BITMAP_ALLOC (NULL);
  bitmap_iterator bi;
  unsigned i;
  bool optimize_speed_p = !optimize_function_for_size_p (cfun);

  enum compiler_param param = optimize_speed_p
			? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
			: PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE;

  /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
     fall back to a target default.  */
  unsigned HOST_WIDE_INT max_scalarization_size
    = global_options_set.x_param_values[param]
      ? PARAM_VALUE (param)
      : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;

  max_scalarization_size *= BITS_PER_UNIT;

  EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
    if (bitmap_bit_p (should_scalarize_away_bitmap, i)
	&& !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
      {
	tree var = candidate (i);

	if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var),
						constant_decl_p (var)))
	  {
	    if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
		<= max_scalarization_size)
	      {
		create_total_scalarization_access (var);
		completely_scalarize (var, TREE_TYPE (var), 0, var);
		statistics_counter_event (cfun,
					  "Totally-scalarized aggregates", 1);
		if (dump_file && (dump_flags & TDF_DETAILS))
		  {
		    fprintf (dump_file, "Will attempt to totally scalarize ");
		    print_generic_expr (dump_file, var);
		    fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
		  }
	      }
	    else if (dump_file && (dump_flags & TDF_DETAILS))
	      {
		fprintf (dump_file, "Too big to totally scalarize: ");
		print_generic_expr (dump_file, var);
		fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
	      }
	  }
      }

  bitmap_copy (tmp, candidate_bitmap);
  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
    {
      tree var = candidate (i);
      struct access *access;

      access = sort_and_splice_var_accesses (var);
      if (!access || !build_access_trees (access))
	disqualify_candidate (var,
			      "No or inhibitingly overlapping accesses.");
    }

  propagate_all_subaccesses ();

  bitmap_copy (tmp, candidate_bitmap);
  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
    {
      tree var = candidate (i);
      struct access *access = get_first_repr_for_decl (var);

      if (analyze_access_trees (access))
	{
	  res++;
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "\nAccess trees for ");
	      print_generic_expr (dump_file, var);
	      fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
	      dump_access_tree (dump_file, access);
	      fprintf (dump_file, "\n");
	    }
	}
      else
	disqualify_candidate (var, "No scalar replacements to be created.");
    }

  BITMAP_FREE (tmp);

  if (res)
    {
      statistics_counter_event (cfun, "Scalarized aggregates", res);
      return true;
    }
  else
    return false;
}

/* Generate statements copying scalar replacements of accesses within a subtree
   into or out of AGG.  ACCESS, all its children, siblings and their children
   are to be processed.  AGG is an aggregate type expression (can be a
   declaration but does not have to be, it can for example also be a mem_ref or
   a series of handled components).  TOP_OFFSET is the offset of the processed
   subtree which has to be subtracted from offsets of individual accesses to
   get corresponding offsets for AGG.  If CHUNK_SIZE is non-null, copy only
   replacements in the interval <start_offset, start_offset + chunk_size>,
   otherwise copy all.  GSI is a statement iterator used to place the new
   statements.  WRITE should be true when the statements should write from AGG
   to the replacement and false if vice versa.  if INSERT_AFTER is true, new
   statements will be added after the current statement in GSI, they will be
   added before the statement otherwise.  */

static void
generate_subtree_copies (struct access *access, tree agg,
			 HOST_WIDE_INT top_offset,
			 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
			 gimple_stmt_iterator *gsi, bool write,
			 bool insert_after, location_t loc)
{
  /* Never write anything into constant pool decls.  See PR70602.  */
  if (!write && constant_decl_p (agg))
    return;
  do
    {
      if (chunk_size && access->offset >= start_offset + chunk_size)
	return;

      if (access->grp_to_be_replaced
	  && (chunk_size == 0
	      || access->offset + access->size > start_offset))
	{
	  tree expr, repl = get_access_replacement (access);
	  gassign *stmt;

	  expr = build_ref_for_model (loc, agg, access->offset - top_offset,
				      access, gsi, insert_after);

	  if (write)
	    {
	      if (access->grp_partial_lhs)
		expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
						 !insert_after,
						 insert_after ? GSI_NEW_STMT
						 : GSI_SAME_STMT);
	      stmt = gimple_build_assign (repl, expr);
	    }
	  else
	    {
	      TREE_NO_WARNING (repl) = 1;
	      if (access->grp_partial_lhs)
		repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
						 !insert_after,
						 insert_after ? GSI_NEW_STMT
						 : GSI_SAME_STMT);
	      stmt = gimple_build_assign (expr, repl);
	    }
	  gimple_set_location (stmt, loc);

	  if (insert_after)
	    gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
	  else
	    gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
	  update_stmt (stmt);
	  sra_stats.subtree_copies++;
	}
      else if (write
	       && access->grp_to_be_debug_replaced
	       && (chunk_size == 0
		   || access->offset + access->size > start_offset))
	{
	  gdebug *ds;
	  tree drhs = build_debug_ref_for_model (loc, agg,
						 access->offset - top_offset,
						 access);
	  ds = gimple_build_debug_bind (get_access_replacement (access),
					drhs, gsi_stmt (*gsi));
	  if (insert_after)
	    gsi_insert_after (gsi, ds, GSI_NEW_STMT);
	  else
	    gsi_insert_before (gsi, ds, GSI_SAME_STMT);
	}

      if (access->first_child)
	generate_subtree_copies (access->first_child, agg, top_offset,
				 start_offset, chunk_size, gsi,
				 write, insert_after, loc);

      access = access->next_sibling;
    }
  while (access);
}

/* Assign zero to all scalar replacements in an access subtree.  ACCESS is the
   root of the subtree to be processed.  GSI is the statement iterator used
   for inserting statements which are added after the current statement if
   INSERT_AFTER is true or before it otherwise.  */

static void
init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
			bool insert_after, location_t loc)

{
  struct access *child;

  if (access->grp_to_be_replaced)
    {
      gassign *stmt;

      stmt = gimple_build_assign (get_access_replacement (access),
				  build_zero_cst (access->type));
      if (insert_after)
	gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
      else
	gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
      update_stmt (stmt);
      gimple_set_location (stmt, loc);
    }
  else if (access->grp_to_be_debug_replaced)
    {
      gdebug *ds
	= gimple_build_debug_bind (get_access_replacement (access),
				   build_zero_cst (access->type),
				   gsi_stmt (*gsi));
      if (insert_after)
	gsi_insert_after (gsi, ds, GSI_NEW_STMT);
      else
	gsi_insert_before (gsi, ds, GSI_SAME_STMT);
    }

  for (child = access->first_child; child; child = child->next_sibling)
    init_subtree_with_zero (child, gsi, insert_after, loc);
}

/* Clobber all scalar replacements in an access subtree.  ACCESS is the
   root of the subtree to be processed.  GSI is the statement iterator used
   for inserting statements which are added after the current statement if
   INSERT_AFTER is true or before it otherwise.  */

static void
clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
		bool insert_after, location_t loc)

{
  struct access *child;

  if (access->grp_to_be_replaced)
    {
      tree rep = get_access_replacement (access);
      tree clobber = build_constructor (access->type, NULL);
      TREE_THIS_VOLATILE (clobber) = 1;
      gimple *stmt = gimple_build_assign (rep, clobber);

      if (insert_after)
	gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
      else
	gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
      update_stmt (stmt);
      gimple_set_location (stmt, loc);
    }

  for (child = access->first_child; child; child = child->next_sibling)
    clobber_subtree (child, gsi, insert_after, loc);
}

/* Search for an access representative for the given expression EXPR and
   return it or NULL if it cannot be found.  */

static struct access *
get_access_for_expr (tree expr)
{
  poly_int64 poffset, psize, pmax_size;
  HOST_WIDE_INT offset, max_size;
  tree base;
  bool reverse;

  /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
     a different size than the size of its argument and we need the latter
     one.  */
  if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
    expr = TREE_OPERAND (expr, 0);

  base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size,
				  &reverse);
  if (!known_size_p (pmax_size)
      || !pmax_size.is_constant (&max_size)
      || !poffset.is_constant (&offset)
      || !DECL_P (base))
    return NULL;

  if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
    return NULL;

  return get_var_base_offset_size_access (base, offset, max_size);
}

/* Replace the expression EXPR with a scalar replacement if there is one and
   generate other statements to do type conversion or subtree copying if
   necessary.  GSI is used to place newly created statements, WRITE is true if
   the expression is being written to (it is on a LHS of a statement or output
   in an assembly statement).  */

static bool
sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
{
  location_t loc;
  struct access *access;
  tree type, bfr, orig_expr;

  if (TREE_CODE (*expr) == BIT_FIELD_REF)
    {
      bfr = *expr;
      expr = &TREE_OPERAND (*expr, 0);
    }
  else
    bfr = NULL_TREE;

  if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
    expr = &TREE_OPERAND (*expr, 0);
  access = get_access_for_expr (*expr);
  if (!access)
    return false;
  type = TREE_TYPE (*expr);
  orig_expr = *expr;

  loc = gimple_location (gsi_stmt (*gsi));
  gimple_stmt_iterator alt_gsi = gsi_none ();
  if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
    {
      alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
      gsi = &alt_gsi;
    }

  if (access->grp_to_be_replaced)
    {
      tree repl = get_access_replacement (access);
      /* If we replace a non-register typed access simply use the original
         access expression to extract the scalar component afterwards.
	 This happens if scalarizing a function return value or parameter
	 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
	 gcc.c-torture/compile/20011217-1.c.

         We also want to use this when accessing a complex or vector which can
         be accessed as a different type too, potentially creating a need for
         type conversion (see PR42196) and when scalarized unions are involved
         in assembler statements (see PR42398).  */
      if (!useless_type_conversion_p (type, access->type))
	{
	  tree ref;

	  ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);

	  if (write)
	    {
	      gassign *stmt;

	      if (access->grp_partial_lhs)
		ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
						 false, GSI_NEW_STMT);
	      stmt = gimple_build_assign (repl, ref);
	      gimple_set_location (stmt, loc);
	      gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
	    }
	  else
	    {
	      gassign *stmt;

	      if (access->grp_partial_lhs)
		repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
						 true, GSI_SAME_STMT);
	      stmt = gimple_build_assign (ref, repl);
	      gimple_set_location (stmt, loc);
	      gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
	    }
	}
      else
	*expr = repl;
      sra_stats.exprs++;
    }
  else if (write && access->grp_to_be_debug_replaced)
    {
      gdebug *ds = gimple_build_debug_bind (get_access_replacement (access),
					    NULL_TREE,
					    gsi_stmt (*gsi));
      gsi_insert_after (gsi, ds, GSI_NEW_STMT);
    }

  if (access->first_child)
    {
      HOST_WIDE_INT start_offset, chunk_size;
      if (bfr
	  && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
	  && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
	{
	  chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
	  start_offset = access->offset
	    + tree_to_uhwi (TREE_OPERAND (bfr, 2));
	}
      else
	start_offset = chunk_size = 0;

      generate_subtree_copies (access->first_child, orig_expr, access->offset,
			       start_offset, chunk_size, gsi, write, write,
			       loc);
    }
  return true;
}

/* Where scalar replacements of the RHS have been written to when a replacement
   of a LHS of an assigments cannot be direclty loaded from a replacement of
   the RHS. */
enum unscalarized_data_handling { SRA_UDH_NONE,  /* Nothing done so far. */
				  SRA_UDH_RIGHT, /* Data flushed to the RHS. */
				  SRA_UDH_LEFT }; /* Data flushed to the LHS. */

struct subreplacement_assignment_data
{
  /* Offset of the access representing the lhs of the assignment.  */
  HOST_WIDE_INT left_offset;

  /* LHS and RHS of the original assignment.  */
  tree assignment_lhs, assignment_rhs;

  /* Access representing the rhs of the whole assignment.  */
  struct access *top_racc;

  /* Stmt iterator used for statement insertions after the original assignment.
   It points to the main GSI used to traverse a BB during function body
   modification.  */
  gimple_stmt_iterator *new_gsi;

  /* Stmt iterator used for statement insertions before the original
   assignment.  Keeps on pointing to the original statement.  */
  gimple_stmt_iterator old_gsi;

  /* Location of the assignment.   */
  location_t loc;

  /* Keeps the information whether we have needed to refresh replacements of
   the LHS and from which side of the assignments this takes place.  */
  enum unscalarized_data_handling refreshed;
};

/* Store all replacements in the access tree rooted in TOP_RACC either to their
   base aggregate if there are unscalarized data or directly to LHS of the
   statement that is pointed to by GSI otherwise.  */

static void
handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
{
  tree src;
  if (sad->top_racc->grp_unscalarized_data)
    {
      src = sad->assignment_rhs;
      sad->refreshed = SRA_UDH_RIGHT;
    }
  else
    {
      src = sad->assignment_lhs;
      sad->refreshed = SRA_UDH_LEFT;
    }
  generate_subtree_copies (sad->top_racc->first_child, src,
			   sad->top_racc->offset, 0, 0,
			   &sad->old_gsi, false, false, sad->loc);
}

/* Try to generate statements to load all sub-replacements in an access subtree
   formed by children of LACC from scalar replacements in the SAD->top_racc
   subtree.  If that is not possible, refresh the SAD->top_racc base aggregate
   and load the accesses from it.  */

static void
load_assign_lhs_subreplacements (struct access *lacc,
				 struct subreplacement_assignment_data *sad)
{
  for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
    {
      HOST_WIDE_INT offset;
      offset = lacc->offset - sad->left_offset + sad->top_racc->offset;

      if (lacc->grp_to_be_replaced)
	{
	  struct access *racc;
	  gassign *stmt;
	  tree rhs;

	  racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
	  if (racc && racc->grp_to_be_replaced)
	    {
	      rhs = get_access_replacement (racc);
	      if (!useless_type_conversion_p (lacc->type, racc->type))
		rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
				       lacc->type, rhs);

	      if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
		rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
						NULL_TREE, true, GSI_SAME_STMT);
	    }
	  else
	    {
	      /* No suitable access on the right hand side, need to load from
		 the aggregate.  See if we have to update it first... */
	      if (sad->refreshed == SRA_UDH_NONE)
		handle_unscalarized_data_in_subtree (sad);

	      if (sad->refreshed == SRA_UDH_LEFT)
		rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
					   lacc->offset - sad->left_offset,
					   lacc, sad->new_gsi, true);
	      else
		rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
					   lacc->offset - sad->left_offset,
					   lacc, sad->new_gsi, true);
	      if (lacc->grp_partial_lhs)
		rhs = force_gimple_operand_gsi (sad->new_gsi,
						rhs, true, NULL_TREE,
						false, GSI_NEW_STMT);
	    }

	  stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
	  gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
	  gimple_set_location (stmt, sad->loc);
	  update_stmt (stmt);
	  sra_stats.subreplacements++;
	}
      else
	{
	  if (sad->refreshed == SRA_UDH_NONE
	      && lacc->grp_read && !lacc->grp_covered)
	    handle_unscalarized_data_in_subtree (sad);

	  if (lacc && lacc->grp_to_be_debug_replaced)
	    {
	      gdebug *ds;
	      tree drhs;
	      struct access *racc = find_access_in_subtree (sad->top_racc,
							    offset,
							    lacc->size);

	      if (racc && racc->grp_to_be_replaced)
		{
		  if (racc->grp_write || constant_decl_p (racc->base))
		    drhs = get_access_replacement (racc);
		  else
		    drhs = NULL;
		}
	      else if (sad->refreshed == SRA_UDH_LEFT)
		drhs = build_debug_ref_for_model (sad->loc, lacc->base,
						  lacc->offset, lacc);
	      else if (sad->refreshed == SRA_UDH_RIGHT)
		drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
						  offset, lacc);
	      else
		drhs = NULL_TREE;
	      if (drhs
		  && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
		drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
					lacc->type, drhs);
	      ds = gimple_build_debug_bind (get_access_replacement (lacc),
					    drhs, gsi_stmt (sad->old_gsi));
	      gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
	    }
	}

      if (lacc->first_child)
	load_assign_lhs_subreplacements (lacc, sad);
    }
}

/* Result code for SRA assignment modification.  */
enum assignment_mod_result { SRA_AM_NONE,       /* nothing done for the stmt */
			     SRA_AM_MODIFIED,  /* stmt changed but not
						  removed */
			     SRA_AM_REMOVED };  /* stmt eliminated */

/* Modify assignments with a CONSTRUCTOR on their RHS.  STMT contains a pointer
   to the assignment and GSI is the statement iterator pointing at it.  Returns
   the same values as sra_modify_assign.  */

static enum assignment_mod_result
sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
{
  tree lhs = gimple_assign_lhs (stmt);
  struct access *acc = get_access_for_expr (lhs);
  if (!acc)
    return SRA_AM_NONE;
  location_t loc = gimple_location (stmt);

  if (gimple_clobber_p (stmt))
    {
      /* Clobber the replacement variable.  */
      clobber_subtree (acc, gsi, !acc->grp_covered, loc);
      /* Remove clobbers of fully scalarized variables, they are dead.  */
      if (acc->grp_covered)
	{
	  unlink_stmt_vdef (stmt);
	  gsi_remove (gsi, true);
	  release_defs (stmt);
	  return SRA_AM_REMOVED;
	}
      else
	return SRA_AM_MODIFIED;
    }

  if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt)) > 0)
    {
      /* I have never seen this code path trigger but if it can happen the
	 following should handle it gracefully.  */
      if (access_has_children_p (acc))
	generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
				 true, true, loc);
      return SRA_AM_MODIFIED;
    }

  if (acc->grp_covered)
    {
      init_subtree_with_zero (acc, gsi, false, loc);
      unlink_stmt_vdef (stmt);
      gsi_remove (gsi, true);
      release_defs (stmt);
      return SRA_AM_REMOVED;
    }
  else
    {
      init_subtree_with_zero (acc, gsi, true, loc);
      return SRA_AM_MODIFIED;
    }
}

/* Create and return a new suitable default definition SSA_NAME for RACC which
   is an access describing an uninitialized part of an aggregate that is being
   loaded.  REG_TREE is used instead of the actual RACC type if that is not of
   a gimple register type.  */

static tree
get_repl_default_def_ssa_name (struct access *racc, tree reg_type)
{
  gcc_checking_assert (!racc->grp_to_be_replaced
		       && !racc->grp_to_be_debug_replaced);
  if (!racc->replacement_decl)
    racc->replacement_decl = create_access_replacement (racc, reg_type);
  return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
}

/* Examine both sides of the assignment statement pointed to by STMT, replace
   them with a scalare replacement if there is one and generate copying of
   replacements if scalarized aggregates have been used in the assignment.  GSI
   is used to hold generated statements for type conversions and subtree
   copying.  */

static enum assignment_mod_result
sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
{
  struct access *lacc, *racc;
  tree lhs, rhs;
  bool modify_this_stmt = false;
  bool force_gimple_rhs = false;
  location_t loc;
  gimple_stmt_iterator orig_gsi = *gsi;

  if (!gimple_assign_single_p (stmt))
    return SRA_AM_NONE;
  lhs = gimple_assign_lhs (stmt);
  rhs = gimple_assign_rhs1 (stmt);

  if (TREE_CODE (rhs) == CONSTRUCTOR)
    return sra_modify_constructor_assign (stmt, gsi);

  if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
      || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
      || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
    {
      modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
					  gsi, false);
      modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
					   gsi, true);
      return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
    }

  lacc = get_access_for_expr (lhs);
  racc = get_access_for_expr (rhs);
  if (!lacc && !racc)
    return SRA_AM_NONE;
  /* Avoid modifying initializations of constant-pool replacements.  */
  if (racc && (racc->replacement_decl == lhs))
    return SRA_AM_NONE;

  loc = gimple_location (stmt);
  if (lacc && lacc->grp_to_be_replaced)
    {
      lhs = get_access_replacement (lacc);
      gimple_assign_set_lhs (stmt, lhs);
      modify_this_stmt = true;
      if (lacc->grp_partial_lhs)
	force_gimple_rhs = true;
      sra_stats.exprs++;
    }

  if (racc && racc->grp_to_be_replaced)
    {
      rhs = get_access_replacement (racc);
      modify_this_stmt = true;
      if (racc->grp_partial_lhs)
	force_gimple_rhs = true;
      sra_stats.exprs++;
    }
  else if (racc
	   && !racc->grp_unscalarized_data
	   && !racc->grp_unscalarizable_region
	   && TREE_CODE (lhs) == SSA_NAME
	   && !access_has_replacements_p (racc))
    {
      rhs = get_repl_default_def_ssa_name (racc, TREE_TYPE (lhs));
      modify_this_stmt = true;
      sra_stats.exprs++;
    }

  if (modify_this_stmt)
    {
      if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
	{
	  /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
	     ???  This should move to fold_stmt which we simply should
	     call after building a VIEW_CONVERT_EXPR here.  */
	  if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
	      && !contains_bitfld_component_ref_p (lhs))
	    {
	      lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
	      gimple_assign_set_lhs (stmt, lhs);
	    }
	  else if (lacc
		   && AGGREGATE_TYPE_P (TREE_TYPE (rhs))
		   && !contains_vce_or_bfcref_p (rhs))
	    rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);

	  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
	    {
	      rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
				     rhs);
	      if (is_gimple_reg_type (TREE_TYPE (lhs))
		  && TREE_CODE (lhs) != SSA_NAME)
		force_gimple_rhs = true;
	    }
	}
    }

  if (lacc && lacc->grp_to_be_debug_replaced)
    {
      tree dlhs = get_access_replacement (lacc);
      tree drhs = unshare_expr (rhs);
      if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
	{
	  if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
	      && !contains_vce_or_bfcref_p (drhs))
	    drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
	  if (drhs
	      && !useless_type_conversion_p (TREE_TYPE (dlhs),
					     TREE_TYPE (drhs)))
	    drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
				    TREE_TYPE (dlhs), drhs);
	}
      gdebug *ds = gimple_build_debug_bind (dlhs, drhs, stmt);
      gsi_insert_before (gsi, ds, GSI_SAME_STMT);
    }

  /* From this point on, the function deals with assignments in between
     aggregates when at least one has scalar reductions of some of its
     components.  There are three possible scenarios: Both the LHS and RHS have
     to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.

     In the first case, we would like to load the LHS components from RHS
     components whenever possible.  If that is not possible, we would like to
     read it directly from the RHS (after updating it by storing in it its own
     components).  If there are some necessary unscalarized data in the LHS,
     those will be loaded by the original assignment too.  If neither of these
     cases happen, the original statement can be removed.  Most of this is done
     by load_assign_lhs_subreplacements.

     In the second case, we would like to store all RHS scalarized components
     directly into LHS and if they cover the aggregate completely, remove the
     statement too.  In the third case, we want the LHS components to be loaded
     directly from the RHS (DSE will remove the original statement if it
     becomes redundant).

     This is a bit complex but manageable when types match and when unions do
     not cause confusion in a way that we cannot really load a component of LHS
     from the RHS or vice versa (the access representing this level can have
     subaccesses that are accessible only through a different union field at a
     higher level - different from the one used in the examined expression).
     Unions are fun.

     Therefore, I specially handle a fourth case, happening when there is a
     specific type cast or it is impossible to locate a scalarized subaccess on
     the other side of the expression.  If that happens, I simply "refresh" the
     RHS by storing in it is scalarized components leave the original statement
     there to do the copying and then load the scalar replacements of the LHS.
     This is what the first branch does.  */

  if (modify_this_stmt
      || gimple_has_volatile_ops (stmt)
      || contains_vce_or_bfcref_p (rhs)
      || contains_vce_or_bfcref_p (lhs)
      || stmt_ends_bb_p (stmt))
    {
      /* No need to copy into a constant-pool, it comes pre-initialized.  */
      if (access_has_children_p (racc) && !constant_decl_p (racc->base))
	generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
				 gsi, false, false, loc);
      if (access_has_children_p (lacc))
	{
	  gimple_stmt_iterator alt_gsi = gsi_none ();
	  if (stmt_ends_bb_p (stmt))
	    {
	      alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
	      gsi = &alt_gsi;
	    }
	  generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
				   gsi, true, true, loc);
	}
      sra_stats.separate_lhs_rhs_handling++;

      /* This gimplification must be done after generate_subtree_copies,
	 lest we insert the subtree copies in the middle of the gimplified
	 sequence.  */
      if (force_gimple_rhs)
	rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
					true, GSI_SAME_STMT);
      if (gimple_assign_rhs1 (stmt) != rhs)
	{
	  modify_this_stmt = true;
	  gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
	  gcc_assert (stmt == gsi_stmt (orig_gsi));
	}

      return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
    }
  else
    {
      if (access_has_children_p (lacc)
	  && access_has_children_p (racc)
	  /* When an access represents an unscalarizable region, it usually
	     represents accesses with variable offset and thus must not be used
	     to generate new memory accesses.  */
	  && !lacc->grp_unscalarizable_region
	  && !racc->grp_unscalarizable_region)
	{
	  struct subreplacement_assignment_data sad;

	  sad.left_offset = lacc->offset;
	  sad.assignment_lhs = lhs;
	  sad.assignment_rhs = rhs;
	  sad.top_racc = racc;
	  sad.old_gsi = *gsi;
	  sad.new_gsi = gsi;
	  sad.loc = gimple_location (stmt);
	  sad.refreshed = SRA_UDH_NONE;

	  if (lacc->grp_read && !lacc->grp_covered)
	    handle_unscalarized_data_in_subtree (&sad);

	  load_assign_lhs_subreplacements (lacc, &sad);
	  if (sad.refreshed != SRA_UDH_RIGHT)
	    {
	      gsi_next (gsi);
	      unlink_stmt_vdef (stmt);
	      gsi_remove (&sad.old_gsi, true);
	      release_defs (stmt);
	      sra_stats.deleted++;
	      return SRA_AM_REMOVED;
	    }
	}
      else
	{
	  if (access_has_children_p (racc)
	      && !racc->grp_unscalarized_data
	      && TREE_CODE (lhs) != SSA_NAME)
	    {
	      if (dump_file)
		{
		  fprintf (dump_file, "Removing load: ");
		  print_gimple_stmt (dump_file, stmt, 0);
		}
	      generate_subtree_copies (racc->first_child, lhs,
				       racc->offset, 0, 0, gsi,
				       false, false, loc);
	      gcc_assert (stmt == gsi_stmt (*gsi));
	      unlink_stmt_vdef (stmt);
	      gsi_remove (gsi, true);
	      release_defs (stmt);
	      sra_stats.deleted++;
	      return SRA_AM_REMOVED;
	    }
	  /* Restore the aggregate RHS from its components so the
	     prevailing aggregate copy does the right thing.  */
	  if (access_has_children_p (racc))
	    generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
				     gsi, false, false, loc);
	  /* Re-load the components of the aggregate copy destination.
	     But use the RHS aggregate to load from to expose more
	     optimization opportunities.  */
	  if (access_has_children_p (lacc))
	    generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
				     0, 0, gsi, true, true, loc);
	}

      return SRA_AM_NONE;
    }
}

/* Set any scalar replacements of values in the constant pool to the initial
   value of the constant.  (Constant-pool decls like *.LC0 have effectively
   been initialized before the program starts, we must do the same for their
   replacements.)  Thus, we output statements like 'SR.1 = *.LC0[0];' into
   the function's entry block.  */

static void
initialize_constant_pool_replacements (void)
{
  gimple_seq seq = NULL;
  gimple_stmt_iterator gsi = gsi_start (seq);
  bitmap_iterator bi;
  unsigned i;

  EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
    {
      tree var = candidate (i);
      if (!constant_decl_p (var))
	continue;
      vec<access_p> *access_vec = get_base_access_vector (var);
      if (!access_vec)
	continue;
      for (unsigned i = 0; i < access_vec->length (); i++)
	{
	  struct access *access = (*access_vec)[i];
	  if (!access->replacement_decl)
	    continue;
	  gassign *stmt
	    = gimple_build_assign (get_access_replacement (access),
				   unshare_expr (access->expr));
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Generating constant initializer: ");
	      print_gimple_stmt (dump_file, stmt, 0);
	      fprintf (dump_file, "\n");
	    }
	  gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
	  update_stmt (stmt);
	}
    }

  seq = gsi_seq (gsi);
  if (seq)
    gsi_insert_seq_on_edge_immediate (
      single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
}

/* Traverse the function body and all modifications as decided in
   analyze_all_variable_accesses.  Return true iff the CFG has been
   changed.  */

static bool
sra_modify_function_body (void)
{
  bool cfg_changed = false;
  basic_block bb;

  initialize_constant_pool_replacements ();

  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple_stmt_iterator gsi = gsi_start_bb (bb);
      while (!gsi_end_p (gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);
	  enum assignment_mod_result assign_result;
	  bool modified = false, deleted = false;
	  tree *t;
	  unsigned i;

	  switch (gimple_code (stmt))
	    {
	    case GIMPLE_RETURN:
	      t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
	      if (*t != NULL_TREE)
		modified |= sra_modify_expr (t, &gsi, false);
	      break;

	    case GIMPLE_ASSIGN:
	      assign_result = sra_modify_assign (stmt, &gsi);
	      modified |= assign_result == SRA_AM_MODIFIED;
	      deleted = assign_result == SRA_AM_REMOVED;
	      break;

	    case GIMPLE_CALL:
	      /* Operands must be processed before the lhs.  */
	      for (i = 0; i < gimple_call_num_args (stmt); i++)
		{
		  t = gimple_call_arg_ptr (stmt, i);
		  modified |= sra_modify_expr (t, &gsi, false);
		}

	      if (gimple_call_lhs (stmt))
		{
		  t = gimple_call_lhs_ptr (stmt);
		  modified |= sra_modify_expr (t, &gsi, true);
		}
	      break;

	    case GIMPLE_ASM:
	      {
		gasm *asm_stmt = as_a <gasm *> (stmt);
		for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
		  {
		    t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
		    modified |= sra_modify_expr (t, &gsi, false);
		  }
		for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
		  {
		    t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
		    modified |= sra_modify_expr (t, &gsi, true);
		  }
	      }
	      break;

	    default:
	      break;
	    }

	  if (modified)
	    {
	      update_stmt (stmt);
	      if (maybe_clean_eh_stmt (stmt)
		  && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
		cfg_changed = true;
	    }
	  if (!deleted)
	    gsi_next (&gsi);
	}
    }

  gsi_commit_edge_inserts ();
  return cfg_changed;
}

/* Generate statements initializing scalar replacements of parts of function
   parameters.  */

static void
initialize_parameter_reductions (void)
{
  gimple_stmt_iterator gsi;
  gimple_seq seq = NULL;
  tree parm;

  gsi = gsi_start (seq);
  for (parm = DECL_ARGUMENTS (current_function_decl);
       parm;
       parm = DECL_CHAIN (parm))
    {
      vec<access_p> *access_vec;
      struct access *access;

      if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
	continue;
      access_vec = get_base_access_vector (parm);
      if (!access_vec)
	continue;

      for (access = (*access_vec)[0];
	   access;
	   access = access->next_grp)
	generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
				 EXPR_LOCATION (parm));
    }

  seq = gsi_seq (gsi);
  if (seq)
    gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
}

/* The "main" function of intraprocedural SRA passes.  Runs the analysis and if
   it reveals there are components of some aggregates to be scalarized, it runs
   the required transformations.  */
static unsigned int
perform_intra_sra (void)
{
  int ret = 0;
  sra_initialize ();

  if (!find_var_candidates ())
    goto out;

  if (!scan_function ())
    goto out;

  if (!analyze_all_variable_accesses ())
    goto out;

  if (sra_modify_function_body ())
    ret = TODO_update_ssa | TODO_cleanup_cfg;
  else
    ret = TODO_update_ssa;
  initialize_parameter_reductions ();

  statistics_counter_event (cfun, "Scalar replacements created",
			    sra_stats.replacements);
  statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
  statistics_counter_event (cfun, "Subtree copy stmts",
			    sra_stats.subtree_copies);
  statistics_counter_event (cfun, "Subreplacement stmts",
			    sra_stats.subreplacements);
  statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
  statistics_counter_event (cfun, "Separate LHS and RHS handling",
			    sra_stats.separate_lhs_rhs_handling);

 out:
  sra_deinitialize ();
  return ret;
}

/* Perform early intraprocedural SRA.  */
static unsigned int
early_intra_sra (void)
{
  sra_mode = SRA_MODE_EARLY_INTRA;
  return perform_intra_sra ();
}

/* Perform "late" intraprocedural SRA.  */
static unsigned int
late_intra_sra (void)
{
  sra_mode = SRA_MODE_INTRA;
  return perform_intra_sra ();
}


static bool
gate_intra_sra (void)
{
  return flag_tree_sra != 0 && dbg_cnt (tree_sra);
}


namespace {

const pass_data pass_data_sra_early =
{
  GIMPLE_PASS, /* type */
  "esra", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_SRA, /* tv_id */
  ( PROP_cfg | PROP_ssa ), /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_update_ssa, /* todo_flags_finish */
};

class pass_sra_early : public gimple_opt_pass
{
public:
  pass_sra_early (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_sra_early, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *) { return gate_intra_sra (); }
  virtual unsigned int execute (function *) { return early_intra_sra (); }

}; // class pass_sra_early

} // anon namespace

gimple_opt_pass *
make_pass_sra_early (gcc::context *ctxt)
{
  return new pass_sra_early (ctxt);
}

namespace {

const pass_data pass_data_sra =
{
  GIMPLE_PASS, /* type */
  "sra", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_SRA, /* tv_id */
  ( PROP_cfg | PROP_ssa ), /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  TODO_update_address_taken, /* todo_flags_start */
  TODO_update_ssa, /* todo_flags_finish */
};

class pass_sra : public gimple_opt_pass
{
public:
  pass_sra (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_sra, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *) { return gate_intra_sra (); }
  virtual unsigned int execute (function *) { return late_intra_sra (); }

}; // class pass_sra

} // anon namespace

gimple_opt_pass *
make_pass_sra (gcc::context *ctxt)
{
  return new pass_sra (ctxt);
}


/* Return true iff PARM (which must be a parm_decl) is an unused scalar
   parameter.  */

static bool
is_unused_scalar_param (tree parm)
{
  tree name;
  return (is_gimple_reg (parm)
	  && (!(name = ssa_default_def (cfun, parm))
	      || has_zero_uses (name)));
}

/* Scan immediate uses of a default definition SSA name of a parameter PARM and
   examine whether there are any direct or otherwise infeasible ones.  If so,
   return true, otherwise return false.  PARM must be a gimple register with a
   non-NULL default definition.  */

static bool
ptr_parm_has_direct_uses (tree parm)
{
  imm_use_iterator ui;
  gimple *stmt;
  tree name = ssa_default_def (cfun, parm);
  bool ret = false;

  FOR_EACH_IMM_USE_STMT (stmt, ui, name)
    {
      int uses_ok = 0;
      use_operand_p use_p;

      if (is_gimple_debug (stmt))
	continue;

      /* Valid uses include dereferences on the lhs and the rhs.  */
      if (gimple_has_lhs (stmt))
	{
	  tree lhs = gimple_get_lhs (stmt);
	  while (handled_component_p (lhs))
	    lhs = TREE_OPERAND (lhs, 0);
	  if (TREE_CODE (lhs) == MEM_REF
	      && TREE_OPERAND (lhs, 0) == name
	      && integer_zerop (TREE_OPERAND (lhs, 1))
	      && types_compatible_p (TREE_TYPE (lhs),
				     TREE_TYPE (TREE_TYPE (name)))
	      && !TREE_THIS_VOLATILE (lhs))
	    uses_ok++;
	}
      if (gimple_assign_single_p (stmt))
	{
	  tree rhs = gimple_assign_rhs1 (stmt);
	  while (handled_component_p (rhs))
	    rhs = TREE_OPERAND (rhs, 0);
	  if (TREE_CODE (rhs) == MEM_REF
	      && TREE_OPERAND (rhs, 0) == name
	      && integer_zerop (TREE_OPERAND (rhs, 1))
	      && types_compatible_p (TREE_TYPE (rhs),
				     TREE_TYPE (TREE_TYPE (name)))
	      && !TREE_THIS_VOLATILE (rhs))
	    uses_ok++;
	}
      else if (is_gimple_call (stmt))
	{
	  unsigned i;
	  for (i = 0; i < gimple_call_num_args (stmt); ++i)
	    {
	      tree arg = gimple_call_arg (stmt, i);
	      while (handled_component_p (arg))
		arg = TREE_OPERAND (arg, 0);
	      if (TREE_CODE (arg) == MEM_REF
		  && TREE_OPERAND (arg, 0) == name
		  && integer_zerop (TREE_OPERAND (arg, 1))
		  && types_compatible_p (TREE_TYPE (arg),
					 TREE_TYPE (TREE_TYPE (name)))
		  && !TREE_THIS_VOLATILE (arg))
		uses_ok++;
	    }
	}

      /* If the number of valid uses does not match the number of
         uses in this stmt there is an unhandled use.  */
      FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
	--uses_ok;

      if (uses_ok != 0)
	ret = true;

      if (ret)
	BREAK_FROM_IMM_USE_STMT (ui);
    }

  return ret;
}

/* Identify candidates for reduction for IPA-SRA based on their type and mark
   them in candidate_bitmap.  Note that these do not necessarily include
   parameter which are unused and thus can be removed.  Return true iff any
   such candidate has been found.  */

static bool
find_param_candidates (void)
{
  tree parm;
  int count = 0;
  bool ret = false;
  const char *msg;

  for (parm = DECL_ARGUMENTS (current_function_decl);
       parm;
       parm = DECL_CHAIN (parm))
    {
      tree type = TREE_TYPE (parm);
      tree_node **slot;

      count++;

      if (TREE_THIS_VOLATILE (parm)
	  || TREE_ADDRESSABLE (parm)
	  || (!is_gimple_reg_type (type) && is_va_list_type (type)))
	continue;

      if (is_unused_scalar_param (parm))
	{
	  ret = true;
	  continue;
	}

      if (POINTER_TYPE_P (type))
	{
	  type = TREE_TYPE (type);

	  if (TREE_CODE (type) == FUNCTION_TYPE
	      || TYPE_VOLATILE (type)
	      || (TREE_CODE (type) == ARRAY_TYPE
		  && TYPE_NONALIASED_COMPONENT (type))
	      || !is_gimple_reg (parm)
	      || is_va_list_type (type)
	      || ptr_parm_has_direct_uses (parm))
	    continue;
	}
      else if (!AGGREGATE_TYPE_P (type))
	continue;

      if (!COMPLETE_TYPE_P (type)
	  || !tree_fits_uhwi_p (TYPE_SIZE (type))
          || tree_to_uhwi (TYPE_SIZE (type)) == 0
	  || (AGGREGATE_TYPE_P (type)
	      && type_internals_preclude_sra_p (type, &msg)))
	continue;

      bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
      slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
      *slot = parm;

      ret = true;
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
	  print_generic_expr (dump_file, parm);
	  fprintf (dump_file, "\n");
	}
    }

  func_param_count = count;
  return ret;
}

/* Callback of walk_aliased_vdefs, marks the access passed as DATA as
   maybe_modified. */

static bool
mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
		     void *data)
{
  struct access *repr = (struct access *) data;

  repr->grp_maybe_modified = 1;
  return true;
}

/* Analyze what representatives (in linked lists accessible from
   REPRESENTATIVES) can be modified by side effects of statements in the
   current function.  */

static void
analyze_modified_params (vec<access_p> representatives)
{
  int i;

  for (i = 0; i < func_param_count; i++)
    {
      struct access *repr;

      for (repr = representatives[i];
	   repr;
	   repr = repr->next_grp)
	{
	  struct access *access;
	  bitmap visited;
	  ao_ref ar;

	  if (no_accesses_p (repr))
	    continue;
	  if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
	      || repr->grp_maybe_modified)
	    continue;

	  ao_ref_init (&ar, repr->expr);
	  visited = BITMAP_ALLOC (NULL);
	  for (access = repr; access; access = access->next_sibling)
	    {
	      /* All accesses are read ones, otherwise grp_maybe_modified would
		 be trivially set.  */
	      walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
				  mark_maybe_modified, repr, &visited);
	      if (repr->grp_maybe_modified)
		break;
	    }
	  BITMAP_FREE (visited);
	}
    }
}

/* Propagate distances in bb_dereferences in the opposite direction than the
   control flow edges, in each step storing the maximum of the current value
   and the minimum of all successors.  These steps are repeated until the table
   stabilizes.  Note that BBs which might terminate the functions (according to
   final_bbs bitmap) never updated in this way.  */

static void
propagate_dereference_distances (void)
{
  basic_block bb;

  auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
  queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  FOR_EACH_BB_FN (bb, cfun)
    {
      queue.quick_push (bb);
      bb->aux = bb;
    }

  while (!queue.is_empty ())
    {
      edge_iterator ei;
      edge e;
      bool change = false;
      int i;

      bb = queue.pop ();
      bb->aux = NULL;

      if (bitmap_bit_p (final_bbs, bb->index))
	continue;

      for (i = 0; i < func_param_count; i++)
	{
	  int idx = bb->index * func_param_count + i;
	  bool first = true;
	  HOST_WIDE_INT inh = 0;

	  FOR_EACH_EDGE (e, ei, bb->succs)
	  {
	    int succ_idx = e->dest->index * func_param_count + i;

	    if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
	      continue;

	    if (first)
	      {
		first = false;
		inh = bb_dereferences [succ_idx];
	      }
	    else if (bb_dereferences [succ_idx] < inh)
	      inh = bb_dereferences [succ_idx];
	  }

	  if (!first && bb_dereferences[idx] < inh)
	    {
	      bb_dereferences[idx] = inh;
	      change = true;
	    }
	}

      if (change && !bitmap_bit_p (final_bbs, bb->index))
	FOR_EACH_EDGE (e, ei, bb->preds)
	  {
	    if (e->src->aux)
	      continue;

	    e->src->aux = e->src;
	    queue.quick_push (e->src);
	  }
    }
}

/* Dump a dereferences TABLE with heading STR to file F.  */

static void
dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
{
  basic_block bb;

  fprintf (dump_file, "%s", str);
  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
		  EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
    {
      fprintf (f, "%4i  %i   ", bb->index, bitmap_bit_p (final_bbs, bb->index));
      if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
	{
	  int i;
	  for (i = 0; i < func_param_count; i++)
	    {
	      int idx = bb->index * func_param_count + i;
	      fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
	    }
	}
      fprintf (f, "\n");
    }
  fprintf (dump_file, "\n");
}

/* Determine what (parts of) parameters passed by reference that are not
   assigned to are not certainly dereferenced in this function and thus the
   dereferencing cannot be safely moved to the caller without potentially
   introducing a segfault.  Mark such REPRESENTATIVES as
   grp_not_necessarilly_dereferenced.

   The dereferenced maximum "distance," i.e. the offset + size of the accessed
   part is calculated rather than simple booleans are calculated for each
   pointer parameter to handle cases when only a fraction of the whole
   aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
   an example).

   The maximum dereference distances for each pointer parameter and BB are
   already stored in bb_dereference.  This routine simply propagates these
   values upwards by propagate_dereference_distances and then compares the
   distances of individual parameters in the ENTRY BB to the equivalent
   distances of each representative of a (fraction of a) parameter.  */

static void
analyze_caller_dereference_legality (vec<access_p> representatives)
{
  int i;

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_dereferences_table (dump_file,
			     "Dereference table before propagation:\n",
			     bb_dereferences);

  propagate_dereference_distances ();

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_dereferences_table (dump_file,
			     "Dereference table after propagation:\n",
			     bb_dereferences);

  for (i = 0; i < func_param_count; i++)
    {
      struct access *repr = representatives[i];
      int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;

      if (!repr || no_accesses_p (repr))
	continue;

      do
	{
	  if ((repr->offset + repr->size) > bb_dereferences[idx])
	    repr->grp_not_necessarilly_dereferenced = 1;
	  repr = repr->next_grp;
	}
      while (repr);
    }
}

/* Return the representative access for the parameter declaration PARM if it is
   a scalar passed by reference which is not written to and the pointer value
   is not used directly.  Thus, if it is legal to dereference it in the caller
   and we can rule out modifications through aliases, such parameter should be
   turned into one passed by value.  Return NULL otherwise.  */

static struct access *
unmodified_by_ref_scalar_representative (tree parm)
{
  int i, access_count;
  struct access *repr;
  vec<access_p> *access_vec;

  access_vec = get_base_access_vector (parm);
  gcc_assert (access_vec);
  repr = (*access_vec)[0];
  if (repr->write)
    return NULL;
  repr->group_representative = repr;

  access_count = access_vec->length ();
  for (i = 1; i < access_count; i++)
    {
      struct access *access = (*access_vec)[i];
      if (access->write)
	return NULL;
      access->group_representative = repr;
      access->next_sibling = repr->next_sibling;
      repr->next_sibling = access;
    }

  repr->grp_read = 1;
  repr->grp_scalar_ptr = 1;
  return repr;
}

/* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
   associated with.  REQ_ALIGN is the minimum required alignment.  */

static bool
access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
{
  unsigned int exp_align;
  /* Avoid issues such as the second simple testcase in PR 42025.  The problem
     is incompatible assign in a call statement (and possibly even in asm
     statements).  This can be relaxed by using a new temporary but only for
     non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
     intraprocedural SRA we deal with this by keeping the old aggregate around,
     something we cannot do in IPA-SRA.)  */
  if (access->write
      && (is_gimple_call (access->stmt)
	  || gimple_code (access->stmt) == GIMPLE_ASM))
    return true;

  exp_align = get_object_alignment (access->expr);
  if (exp_align < req_align)
    return true;

  return false;
}


/* Sort collected accesses for parameter PARM, identify representatives for
   each accessed region and link them together.  Return NULL if there are
   different but overlapping accesses, return the special ptr value meaning
   there are no accesses for this parameter if that is the case and return the
   first representative otherwise.  Set *RO_GRP if there is a group of accesses
   with only read (i.e. no write) accesses.  */

static struct access *
splice_param_accesses (tree parm, bool *ro_grp)
{
  int i, j, access_count, group_count;
  int total_size = 0;
  struct access *access, *res, **prev_acc_ptr = &res;
  vec<access_p> *access_vec;

  access_vec = get_base_access_vector (parm);
  if (!access_vec)
    return &no_accesses_representant;
  access_count = access_vec->length ();

  access_vec->qsort (compare_access_positions);

  i = 0;
  total_size = 0;
  group_count = 0;
  while (i < access_count)
    {
      bool modification;
      tree a1_alias_type;
      access = (*access_vec)[i];
      modification = access->write;
      if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
	return NULL;
      a1_alias_type = reference_alias_ptr_type (access->expr);

      /* Access is about to become group representative unless we find some
	 nasty overlap which would preclude us from breaking this parameter
	 apart. */

      j = i + 1;
      while (j < access_count)
	{
	  struct access *ac2 = (*access_vec)[j];
	  if (ac2->offset != access->offset)
	    {
	      /* All or nothing law for parameters. */
	      if (access->offset + access->size > ac2->offset)
		return NULL;
	      else
		break;
	    }
	  else if (ac2->size != access->size)
	    return NULL;

	  if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
	      || (ac2->type != access->type
		  && (TREE_ADDRESSABLE (ac2->type)
		      || TREE_ADDRESSABLE (access->type)))
	      || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
	    return NULL;

	  modification |= ac2->write;
	  ac2->group_representative = access;
	  ac2->next_sibling = access->next_sibling;
	  access->next_sibling = ac2;
	  j++;
	}

      group_count++;
      access->grp_maybe_modified = modification;
      if (!modification)
	*ro_grp = true;
      *prev_acc_ptr = access;
      prev_acc_ptr = &access->next_grp;
      total_size += access->size;
      i = j;
    }

  gcc_assert (group_count > 0);
  return res;
}

/* Decide whether parameters with representative accesses given by REPR should
   be reduced into components.  */

static int
decide_one_param_reduction (struct access *repr)
{
  HOST_WIDE_INT total_size, cur_parm_size;
  bool by_ref;
  tree parm;

  parm = repr->base;
  cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
  gcc_assert (cur_parm_size > 0);

  if (POINTER_TYPE_P (TREE_TYPE (parm)))
    by_ref = true;
  else
    by_ref = false;

  if (dump_file)
    {
      struct access *acc;
      fprintf (dump_file, "Evaluating PARAM group sizes for ");
      print_generic_expr (dump_file, parm);
      fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
      for (acc = repr; acc; acc = acc->next_grp)
	dump_access (dump_file, acc, true);
    }

  total_size = 0;
  int new_param_count = 0;

  for (; repr; repr = repr->next_grp)
    {
      gcc_assert (parm == repr->base);

      /* Taking the address of a non-addressable field is verboten.  */
      if (by_ref && repr->non_addressable)
	return 0;

      /* Do not decompose a non-BLKmode param in a way that would
         create BLKmode params.  Especially for by-reference passing
	 (thus, pointer-type param) this is hardly worthwhile.  */
      if (DECL_MODE (parm) != BLKmode
	  && TYPE_MODE (repr->type) == BLKmode)
	return 0;

      if (!by_ref || (!repr->grp_maybe_modified
		      && !repr->grp_not_necessarilly_dereferenced))
	total_size += repr->size;
      else
	total_size += cur_parm_size;

      new_param_count++;
    }

  gcc_assert (new_param_count > 0);

  if (!by_ref)
    {
      if (total_size >= cur_parm_size)
	return 0;
    }
  else
    {
      int parm_num_limit;
      if (optimize_function_for_size_p (cfun))
	parm_num_limit = 1;
      else
	parm_num_limit = PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR);

      if (new_param_count > parm_num_limit
	  || total_size > (parm_num_limit * cur_parm_size))
	return 0;
    }

  if (dump_file)
    fprintf (dump_file, "    ....will be split into %i components\n",
	     new_param_count);
  return new_param_count;
}

/* The order of the following enums is important, we need to do extra work for
   UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES.  */
enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
			  MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };

/* Identify representatives of all accesses to all candidate parameters for
   IPA-SRA.  Return result based on what representatives have been found. */

static enum ipa_splicing_result
splice_all_param_accesses (vec<access_p> &representatives)
{
  enum ipa_splicing_result result = NO_GOOD_ACCESS;
  tree parm;
  struct access *repr;

  representatives.create (func_param_count);

  for (parm = DECL_ARGUMENTS (current_function_decl);
       parm;
       parm = DECL_CHAIN (parm))
    {
      if (is_unused_scalar_param (parm))
	{
	  representatives.quick_push (&no_accesses_representant);
	  if (result == NO_GOOD_ACCESS)
	    result = UNUSED_PARAMS;
	}
      else if (POINTER_TYPE_P (TREE_TYPE (parm))
	       && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
	       && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
	{
	  repr = unmodified_by_ref_scalar_representative (parm);
	  representatives.quick_push (repr);
	  if (repr)
	    result = UNMODIF_BY_REF_ACCESSES;
	}
      else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
	{
	  bool ro_grp = false;
	  repr = splice_param_accesses (parm, &ro_grp);
	  representatives.quick_push (repr);

	  if (repr && !no_accesses_p (repr))
	    {
	      if (POINTER_TYPE_P (TREE_TYPE (parm)))
		{
		  if (ro_grp)
		    result = UNMODIF_BY_REF_ACCESSES;
		  else if (result < MODIF_BY_REF_ACCESSES)
		    result = MODIF_BY_REF_ACCESSES;
		}
	      else if (result < BY_VAL_ACCESSES)
		result = BY_VAL_ACCESSES;
	    }
	  else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
	    result = UNUSED_PARAMS;
	}
      else
	representatives.quick_push (NULL);
    }

  if (result == NO_GOOD_ACCESS)
    {
      representatives.release ();
      return NO_GOOD_ACCESS;
    }

  return result;
}

/* Return the index of BASE in PARMS.  Abort if it is not found.  */

static inline int
get_param_index (tree base, vec<tree> parms)
{
  int i, len;

  len = parms.length ();
  for (i = 0; i < len; i++)
    if (parms[i] == base)
      return i;
  gcc_unreachable ();
}

/* Convert the decisions made at the representative level into compact
   parameter adjustments.  REPRESENTATIVES are pointers to first
   representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
   final number of adjustments.  */

static ipa_parm_adjustment_vec
turn_representatives_into_adjustments (vec<access_p> representatives,
				       int adjustments_count)
{
  vec<tree> parms;
  ipa_parm_adjustment_vec adjustments;
  tree parm;
  int i;

  gcc_assert (adjustments_count > 0);
  parms = ipa_get_vector_of_formal_parms (current_function_decl);
  adjustments.create (adjustments_count);
  parm = DECL_ARGUMENTS (current_function_decl);
  for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
    {
      struct access *repr = representatives[i];

      if (!repr || no_accesses_p (repr))
	{
	  struct ipa_parm_adjustment adj;

	  memset (&adj, 0, sizeof (adj));
	  adj.base_index = get_param_index (parm, parms);
	  adj.base = parm;
	  if (!repr)
	    adj.op = IPA_PARM_OP_COPY;
	  else
	    adj.op = IPA_PARM_OP_REMOVE;
	  adj.arg_prefix = "ISRA";
	  adjustments.quick_push (adj);
	}
      else
	{
	  struct ipa_parm_adjustment adj;
	  int index = get_param_index (parm, parms);

	  for (; repr; repr = repr->next_grp)
	    {
	      memset (&adj, 0, sizeof (adj));
	      gcc_assert (repr->base == parm);
	      adj.base_index = index;
	      adj.base = repr->base;
	      adj.type = repr->type;
	      adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
	      adj.offset = repr->offset;
	      adj.reverse = repr->reverse;
	      adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
			    && (repr->grp_maybe_modified
				|| repr->grp_not_necessarilly_dereferenced));
	      adj.arg_prefix = "ISRA";
	      adjustments.quick_push (adj);
	    }
	}
    }
  parms.release ();
  return adjustments;
}

/* Analyze the collected accesses and produce a plan what to do with the
   parameters in the form of adjustments, NULL meaning nothing.  */

static ipa_parm_adjustment_vec
analyze_all_param_acesses (void)
{
  enum ipa_splicing_result repr_state;
  bool proceed = false;
  int i, adjustments_count = 0;
  vec<access_p> representatives;
  ipa_parm_adjustment_vec adjustments;

  repr_state = splice_all_param_accesses (representatives);
  if (repr_state == NO_GOOD_ACCESS)
    return ipa_parm_adjustment_vec ();

  /* If there are any parameters passed by reference which are not modified
     directly, we need to check whether they can be modified indirectly.  */
  if (repr_state == UNMODIF_BY_REF_ACCESSES)
    {
      analyze_caller_dereference_legality (representatives);
      analyze_modified_params (representatives);
    }

  for (i = 0; i < func_param_count; i++)
    {
      struct access *repr = representatives[i];

      if (repr && !no_accesses_p (repr))
	{
	  if (repr->grp_scalar_ptr)
	    {
	      adjustments_count++;
	      if (repr->grp_not_necessarilly_dereferenced
		  || repr->grp_maybe_modified)
		representatives[i] = NULL;
	      else
		{
		  proceed = true;
		  sra_stats.scalar_by_ref_to_by_val++;
		}
	    }
	  else
	    {
	      int new_components = decide_one_param_reduction (repr);

	      if (new_components == 0)
		{
		  representatives[i] = NULL;
		  adjustments_count++;
		}
	      else
		{
		  adjustments_count += new_components;
		  sra_stats.aggregate_params_reduced++;
		  sra_stats.param_reductions_created += new_components;
		  proceed = true;
		}
	    }
	}
      else
	{
	  if (no_accesses_p (repr))
	    {
	      proceed = true;
	      sra_stats.deleted_unused_parameters++;
	    }
	  adjustments_count++;
	}
    }

  if (!proceed && dump_file)
    fprintf (dump_file, "NOT proceeding to change params.\n");

  if (proceed)
    adjustments = turn_representatives_into_adjustments (representatives,
							 adjustments_count);
  else
    adjustments = ipa_parm_adjustment_vec ();

  representatives.release ();
  return adjustments;
}

/* If a parameter replacement identified by ADJ does not yet exist in the form
   of declaration, create it and record it, otherwise return the previously
   created one.  */

static tree
get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
{
  tree repl;
  if (!adj->new_ssa_base)
    {
      char *pretty_name = make_fancy_name (adj->base);

      repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
      DECL_NAME (repl) = get_identifier (pretty_name);
      DECL_NAMELESS (repl) = 1;
      obstack_free (&name_obstack, pretty_name);

      adj->new_ssa_base = repl;
    }
  else
    repl = adj->new_ssa_base;
  return repl;
}

/* Find the first adjustment for a particular parameter BASE in a vector of
   ADJUSTMENTS which is not a copy_param.  Return NULL if there is no such
   adjustment. */

static struct ipa_parm_adjustment *
get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
{
  int i, len;

  len = adjustments.length ();
  for (i = 0; i < len; i++)
    {
      struct ipa_parm_adjustment *adj;

      adj = &adjustments[i];
      if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
	return adj;
    }

  return NULL;
}

/* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
   parameter which is to be removed because its value is not used, create a new
   SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
   original with it and return it.  If there is no need to re-map, return NULL.
   ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments.  */

static tree
replace_removed_params_ssa_names (tree old_name, gimple *stmt,
				  ipa_parm_adjustment_vec adjustments)
{
  struct ipa_parm_adjustment *adj;
  tree decl, repl, new_name;

  if (TREE_CODE (old_name) != SSA_NAME)
    return NULL;

  decl = SSA_NAME_VAR (old_name);
  if (decl == NULL_TREE
      || TREE_CODE (decl) != PARM_DECL)
    return NULL;

  adj = get_adjustment_for_base (adjustments, decl);
  if (!adj)
    return NULL;

  repl = get_replaced_param_substitute (adj);
  new_name = make_ssa_name (repl, stmt);
  SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
    = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);

  if (dump_file)
    {
      fprintf (dump_file, "replacing an SSA name of a removed param ");
      print_generic_expr (dump_file, old_name);
      fprintf (dump_file, " with ");
      print_generic_expr (dump_file, new_name);
      fprintf (dump_file, "\n");
    }

  replace_uses_by (old_name, new_name);
  return new_name;
}

/* If the statement STMT contains any expressions that need to replaced with a
   different one as noted by ADJUSTMENTS, do so.  Handle any potential type
   incompatibilities (GSI is used to accommodate conversion statements and must
   point to the statement).  Return true iff the statement was modified.  */

static bool
sra_ipa_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
		       ipa_parm_adjustment_vec adjustments)
{
  tree *lhs_p, *rhs_p;
  bool any;

  if (!gimple_assign_single_p (stmt))
    return false;

  rhs_p = gimple_assign_rhs1_ptr (stmt);
  lhs_p = gimple_assign_lhs_ptr (stmt);

  any = ipa_modify_expr (rhs_p, false, adjustments);
  any |= ipa_modify_expr (lhs_p, false, adjustments);
  if (any)
    {
      tree new_rhs = NULL_TREE;

      if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
	{
	  if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
	    {
	      /* V_C_Es of constructors can cause trouble (PR 42714).  */
	      if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
		*rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
	      else
		*rhs_p = build_constructor (TREE_TYPE (*lhs_p),
					    NULL);
	    }
	  else
	    new_rhs = fold_build1_loc (gimple_location (stmt),
				       VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
				       *rhs_p);
	}
      else if (REFERENCE_CLASS_P (*rhs_p)
	       && is_gimple_reg_type (TREE_TYPE (*lhs_p))
	       && !is_gimple_reg (*lhs_p))
	/* This can happen when an assignment in between two single field
	   structures is turned into an assignment in between two pointers to
	   scalars (PR 42237).  */
	new_rhs = *rhs_p;

      if (new_rhs)
	{
	  tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
					       true, GSI_SAME_STMT);

	  gimple_assign_set_rhs_from_tree (gsi, tmp);
	}

      return true;
    }

  return false;
}

/* Traverse the function body and all modifications as described in
   ADJUSTMENTS.  Return true iff the CFG has been changed.  */

bool
ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
{
  bool cfg_changed = false;
  basic_block bb;

  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple_stmt_iterator gsi;

      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
	  tree new_lhs, old_lhs = gimple_phi_result (phi);
	  new_lhs = replace_removed_params_ssa_names (old_lhs, phi, adjustments);
	  if (new_lhs)
	    {
	      gimple_phi_set_result (phi, new_lhs);
	      release_ssa_name (old_lhs);
	    }
	}

      gsi = gsi_start_bb (bb);
      while (!gsi_end_p (gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);
	  bool modified = false;
	  tree *t;
	  unsigned i;

	  switch (gimple_code (stmt))
	    {
	    case GIMPLE_RETURN:
	      t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
	      if (*t != NULL_TREE)
		modified |= ipa_modify_expr (t, true, adjustments);
	      break;

	    case GIMPLE_ASSIGN:
	      modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments);
	      break;

	    case GIMPLE_CALL:
	      /* Operands must be processed before the lhs.  */
	      for (i = 0; i < gimple_call_num_args (stmt); i++)
		{
		  t = gimple_call_arg_ptr (stmt, i);
		  modified |= ipa_modify_expr (t, true, adjustments);
		}

	      if (gimple_call_lhs (stmt))
		{
		  t = gimple_call_lhs_ptr (stmt);
		  modified |= ipa_modify_expr (t, false, adjustments);
		}
	      break;

	    case GIMPLE_ASM:
	      {
		gasm *asm_stmt = as_a <gasm *> (stmt);
		for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
		  {
		    t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
		    modified |= ipa_modify_expr (t, true, adjustments);
		  }
		for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
		  {
		    t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
		    modified |= ipa_modify_expr (t, false, adjustments);
		  }
	      }
	      break;

	    default:
	      break;
	    }

	  def_operand_p defp;
	  ssa_op_iter iter;
	  FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
	    {
	      tree old_def = DEF_FROM_PTR (defp);
	      if (tree new_def = replace_removed_params_ssa_names (old_def, stmt,
								   adjustments))
		{
		  SET_DEF (defp, new_def);
		  release_ssa_name (old_def);
		  modified = true;
		}
	    }

	  if (modified)
	    {
	      update_stmt (stmt);
	      if (maybe_clean_eh_stmt (stmt)
		  && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
		cfg_changed = true;
	    }
	  gsi_next (&gsi);
	}
    }

  return cfg_changed;
}

/* Call gimple_debug_bind_reset_value on all debug statements describing
   gimple register parameters that are being removed or replaced.  */

static void
sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
{
  int i, len;
  gimple_stmt_iterator *gsip = NULL, gsi;

  if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
    {
      gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
      gsip = &gsi;
    }
  len = adjustments.length ();
  for (i = 0; i < len; i++)
    {
      struct ipa_parm_adjustment *adj;
      imm_use_iterator ui;
      gimple *stmt;
      gdebug *def_temp;
      tree name, vexpr, copy = NULL_TREE;
      use_operand_p use_p;

      adj = &adjustments[i];
      if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
	continue;
      name = ssa_default_def (cfun, adj->base);
      vexpr = NULL;
      if (name)
	FOR_EACH_IMM_USE_STMT (stmt, ui, name)
	  {
	    if (gimple_clobber_p (stmt))
	      {
		gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
		unlink_stmt_vdef (stmt);
		gsi_remove (&cgsi, true);
		release_defs (stmt);
		continue;
	      }
	    /* All other users must have been removed by
	       ipa_sra_modify_function_body.  */
	    gcc_assert (is_gimple_debug (stmt));
	    if (vexpr == NULL && gsip != NULL)
	      {
		gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
		vexpr = make_node (DEBUG_EXPR_DECL);
		def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
							   NULL);
		DECL_ARTIFICIAL (vexpr) = 1;
		TREE_TYPE (vexpr) = TREE_TYPE (name);
		SET_DECL_MODE (vexpr, DECL_MODE (adj->base));
		gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
	      }
	    if (vexpr)
	      {
		FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
		  SET_USE (use_p, vexpr);
	      }
	    else
	      gimple_debug_bind_reset_value (stmt);
	    update_stmt (stmt);
	  }
      /* Create a VAR_DECL for debug info purposes.  */
      if (!DECL_IGNORED_P (adj->base))
	{
	  copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
			     VAR_DECL, DECL_NAME (adj->base),
			     TREE_TYPE (adj->base));
	  if (DECL_PT_UID_SET_P (adj->base))
	    SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
	  TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
	  TREE_READONLY (copy) = TREE_READONLY (adj->base);
	  TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
	  DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
	  DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
	  DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
	  DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
	  DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
	  SET_DECL_RTL (copy, 0);
	  TREE_USED (copy) = 1;
	  DECL_CONTEXT (copy) = current_function_decl;
	  add_local_decl (cfun, copy);
	  DECL_CHAIN (copy) =
	    BLOCK_VARS (DECL_INITIAL (current_function_decl));
	  BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
	}
      if (gsip != NULL && copy && target_for_debug_bind (adj->base))
	{
	  gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
	  if (vexpr)
	    def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
	  else
	    def_temp = gimple_build_debug_source_bind (copy, adj->base,
						       NULL);
	  gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
	}
    }
}

/* Return false if all callers have at least as many actual arguments as there
   are formal parameters in the current function and that their types
   match.  */

static bool
some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
					  void *data ATTRIBUTE_UNUSED)
{
  struct cgraph_edge *cs;
  for (cs = node->callers; cs; cs = cs->next_caller)
    if (!cs->call_stmt || !callsite_arguments_match_p (cs->call_stmt))
      return true;

  return false;
}

/* Return false if all callers have vuse attached to a call statement.  */

static bool
some_callers_have_no_vuse_p (struct cgraph_node *node,
			     void *data ATTRIBUTE_UNUSED)
{
  struct cgraph_edge *cs;
  for (cs = node->callers; cs; cs = cs->next_caller)
    if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
      return true;

  return false;
}

/* Convert all callers of NODE.  */

static bool
convert_callers_for_node (struct cgraph_node *node,
		          void *data)
{
  ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
  bitmap recomputed_callers = BITMAP_ALLOC (NULL);
  struct cgraph_edge *cs;

  for (cs = node->callers; cs; cs = cs->next_caller)
    {
      push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));

      if (dump_file)
	fprintf (dump_file, "Adjusting call %s -> %s\n",
		 cs->caller->dump_name (), cs->callee->dump_name ());

      ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);

      pop_cfun ();
    }

  for (cs = node->callers; cs; cs = cs->next_caller)
    if (bitmap_set_bit (recomputed_callers, cs->caller->get_uid ())
	&& gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
      compute_fn_summary (cs->caller, true);
  BITMAP_FREE (recomputed_callers);

  return true;
}

/* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS.  */

static void
convert_callers (struct cgraph_node *node, tree old_decl,
		 ipa_parm_adjustment_vec adjustments)
{
  basic_block this_block;

  node->call_for_symbol_and_aliases (convert_callers_for_node,
				     &adjustments, false);

  if (!encountered_recursive_call)
    return;

  FOR_EACH_BB_FN (this_block, cfun)
    {
      gimple_stmt_iterator gsi;

      for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
        {
	  gcall *stmt;
	  tree call_fndecl;
	  stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
	  if (!stmt)
	    continue;
	  call_fndecl = gimple_call_fndecl (stmt);
	  if (call_fndecl == old_decl)
	    {
	      if (dump_file)
		fprintf (dump_file, "Adjusting recursive call");
	      gimple_call_set_fndecl (stmt, node->decl);
	      ipa_modify_call_arguments (NULL, stmt, adjustments);
	    }
	}
    }

  return;
}

/* Perform all the modification required in IPA-SRA for NODE to have parameters
   as given in ADJUSTMENTS.  Return true iff the CFG has been changed.  */

static bool
modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
{
  struct cgraph_node *new_node;
  bool cfg_changed;

  cgraph_edge::rebuild_edges ();
  free_dominance_info (CDI_DOMINATORS);
  pop_cfun ();

  /* This must be done after rebuilding cgraph edges for node above.
     Otherwise any recursive calls to node that are recorded in
     redirect_callers will be corrupted.  */
  vec<cgraph_edge *> redirect_callers = node->collect_callers ();
  new_node = node->create_version_clone_with_body (redirect_callers, NULL,
						   NULL, false, NULL, NULL,
						   "isra");
  redirect_callers.release ();

  push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
  ipa_modify_formal_parameters (current_function_decl, adjustments);
  cfg_changed = ipa_sra_modify_function_body (adjustments);
  sra_ipa_reset_debug_stmts (adjustments);
  convert_callers (new_node, node->decl, adjustments);
  new_node->make_local ();
  return cfg_changed;
}

/* Means of communication between ipa_sra_check_caller and
   ipa_sra_preliminary_function_checks.  */

struct ipa_sra_check_caller_data
{
  bool has_callers;
  bool bad_arg_alignment;
  bool has_thunk;
};

/* If NODE has a caller, mark that fact in DATA which is pointer to
   ipa_sra_check_caller_data.  Also check all aggregate arguments in all known
   calls if they are unit aligned and if not, set the appropriate flag in DATA
   too. */

static bool
ipa_sra_check_caller (struct cgraph_node *node, void *data)
{
  if (!node->callers)
    return false;

  struct ipa_sra_check_caller_data *iscc;
  iscc = (struct ipa_sra_check_caller_data *) data;
  iscc->has_callers = true;

  for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
    {
      if (cs->caller->thunk.thunk_p)
	{
	  iscc->has_thunk = true;
	  return true;
	}
      gimple *call_stmt = cs->call_stmt;
      unsigned count = gimple_call_num_args (call_stmt);
      for (unsigned i = 0; i < count; i++)
	{
	  tree arg = gimple_call_arg (call_stmt, i);
	  if (is_gimple_reg (arg))
	      continue;

	  tree offset;
	  poly_int64 bitsize, bitpos;
	  machine_mode mode;
	  int unsignedp, reversep, volatilep = 0;
	  get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
			       &unsignedp, &reversep, &volatilep);
	  if (!multiple_p (bitpos, BITS_PER_UNIT))
	    {
	      iscc->bad_arg_alignment = true;
	      return true;
	    }
	}
    }

  return false;
}

/* Return false the function is apparently unsuitable for IPA-SRA based on it's
   attributes, return true otherwise.  NODE is the cgraph node of the current
   function.  */

static bool
ipa_sra_preliminary_function_checks (struct cgraph_node *node)
{
  if (!node->can_be_local_p ())
    {
      if (dump_file)
	fprintf (dump_file, "Function not local to this compilation unit.\n");
      return false;
    }

  if (!node->local.can_change_signature)
    {
      if (dump_file)
	fprintf (dump_file, "Function cannot change signature.\n");
      return false;
    }

  if (!tree_versionable_function_p (node->decl))
    {
      if (dump_file)
	fprintf (dump_file, "Function is not versionable.\n");
      return false;
    }

  if (!opt_for_fn (node->decl, optimize)
      || !opt_for_fn (node->decl, flag_ipa_sra))
    {
      if (dump_file)
	fprintf (dump_file, "Function not optimized.\n");
      return false;
    }

  if (DECL_VIRTUAL_P (current_function_decl))
    {
      if (dump_file)
	fprintf (dump_file, "Function is a virtual method.\n");
      return false;
    }

  if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
      && ipa_fn_summaries->get (node)
      && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
    {
      if (dump_file)
	fprintf (dump_file, "Function too big to be made truly local.\n");
      return false;
    }

  if (cfun->stdarg)
    {
      if (dump_file)
	fprintf (dump_file, "Function uses stdarg. \n");
      return false;
    }

  if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
    return false;

  if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
    {
      if (dump_file)
	fprintf (dump_file, "Always inline function will be inlined "
		 "anyway. \n");
      return false;
    }

  struct ipa_sra_check_caller_data iscc;
  memset (&iscc, 0, sizeof(iscc));
  node->call_for_symbol_and_aliases (ipa_sra_check_caller, &iscc, true);
  if (!iscc.has_callers)
    {
      if (dump_file)
	fprintf (dump_file,
		 "Function has no callers in this compilation unit.\n");
      return false;
    }

  if (iscc.bad_arg_alignment)
    {
      if (dump_file)
	fprintf (dump_file,
		 "A function call has an argument with non-unit alignment.\n");
      return false;
    }

  if (iscc.has_thunk)
    {
      if (dump_file)
	fprintf (dump_file,
		 "A has thunk.\n");
      return false;
    }

  return true;
}

/* Perform early interprocedural SRA.  */

static unsigned int
ipa_early_sra (void)
{
  struct cgraph_node *node = cgraph_node::get (current_function_decl);
  ipa_parm_adjustment_vec adjustments;
  int ret = 0;

  if (!ipa_sra_preliminary_function_checks (node))
    return 0;

  sra_initialize ();
  sra_mode = SRA_MODE_EARLY_IPA;

  if (!find_param_candidates ())
    {
      if (dump_file)
	fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
      goto simple_out;
    }

  if (node->call_for_symbol_and_aliases
       (some_callers_have_mismatched_arguments_p, NULL, true))
    {
      if (dump_file)
	fprintf (dump_file, "There are callers with insufficient number of "
		 "arguments or arguments with type mismatches.\n");
      goto simple_out;
    }

  if (node->call_for_symbol_and_aliases
       (some_callers_have_no_vuse_p, NULL, true))
    {
      if (dump_file)
	fprintf (dump_file, "There are callers with no VUSE attached "
		 "to a call stmt.\n");
      goto simple_out;
    }

  bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
				 func_param_count
				 * last_basic_block_for_fn (cfun));
  final_bbs = BITMAP_ALLOC (NULL);

  scan_function ();
  if (encountered_apply_args)
    {
      if (dump_file)
	fprintf (dump_file, "Function calls  __builtin_apply_args().\n");
      goto out;
    }

  if (encountered_unchangable_recursive_call)
    {
      if (dump_file)
	fprintf (dump_file, "Function calls itself with insufficient "
		 "number of arguments.\n");
      goto out;
    }

  adjustments = analyze_all_param_acesses ();
  if (!adjustments.exists ())
    goto out;
  if (dump_file)
    ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);

  if (modify_function (node, adjustments))
    ret = TODO_update_ssa | TODO_cleanup_cfg;
  else
    ret = TODO_update_ssa;
  adjustments.release ();

  statistics_counter_event (cfun, "Unused parameters deleted",
			    sra_stats.deleted_unused_parameters);
  statistics_counter_event (cfun, "Scalar parameters converted to by-value",
			    sra_stats.scalar_by_ref_to_by_val);
  statistics_counter_event (cfun, "Aggregate parameters broken up",
			    sra_stats.aggregate_params_reduced);
  statistics_counter_event (cfun, "Aggregate parameter components created",
			    sra_stats.param_reductions_created);

 out:
  BITMAP_FREE (final_bbs);
  free (bb_dereferences);
 simple_out:
  sra_deinitialize ();
  return ret;
}

namespace {

const pass_data pass_data_early_ipa_sra =
{
  GIMPLE_PASS, /* type */
  "eipa_sra", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_IPA_SRA, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_dump_symtab, /* todo_flags_finish */
};

class pass_early_ipa_sra : public gimple_opt_pass
{
public:
  pass_early_ipa_sra (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
  virtual unsigned int execute (function *) { return ipa_early_sra (); }

}; // class pass_early_ipa_sra

} // anon namespace

gimple_opt_pass *
make_pass_early_ipa_sra (gcc::context *ctxt)
{
  return new pass_early_ipa_sra (ctxt);
}
