/* Loop invariant motion.
   Copyright (C) 2003-2022 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "fold-const.h"
#include "cfganal.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop.h"
#include "tree-into-ssa.h"
#include "cfgloop.h"
#include "tree-affine.h"
#include "tree-ssa-propagate.h"
#include "trans-mem.h"
#include "gimple-fold.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-loop-niter.h"
#include "alias.h"
#include "builtins.h"
#include "tree-dfa.h"
#include "dbgcnt.h"

/* TODO:  Support for predicated code motion.  I.e.

   while (1)
     {
       if (cond)
	 {
	   a = inv;
	   something;
	 }
     }

   Where COND and INV are invariants, but evaluating INV may trap or be
   invalid from some other reason if !COND.  This may be transformed to

   if (cond)
     a = inv;
   while (1)
     {
       if (cond)
	 something;
     }  */

/* The auxiliary data kept for each statement.  */

struct lim_aux_data
{
  class loop *max_loop;	/* The outermost loop in that the statement
				   is invariant.  */

  class loop *tgt_loop;	/* The loop out of that we want to move the
				   invariant.  */

  class loop *always_executed_in;
				/* The outermost loop for that we are sure
				   the statement is executed if the loop
				   is entered.  */

  unsigned cost;		/* Cost of the computation performed by the
				   statement.  */

  unsigned ref;			/* The simple_mem_ref in this stmt or 0.  */

  vec<gimple *> depends;	/* Vector of statements that must be also
				   hoisted out of the loop when this statement
				   is hoisted; i.e. those that define the
				   operands of the statement and are inside of
				   the MAX_LOOP loop.  */
};

/* Maps statements to their lim_aux_data.  */

static hash_map<gimple *, lim_aux_data *> *lim_aux_data_map;

/* Description of a memory reference location.  */

struct mem_ref_loc
{
  tree *ref;			/* The reference itself.  */
  gimple *stmt;			/* The statement in that it occurs.  */
};


/* Description of a memory reference.  */

class im_mem_ref
{
public:
  unsigned id : 30;		/* ID assigned to the memory reference
				   (its index in memory_accesses.refs_list)  */
  unsigned ref_canonical : 1;   /* Whether mem.ref was canonicalized.  */
  unsigned ref_decomposed : 1;  /* Whether the ref was hashed from mem.  */
  hashval_t hash;		/* Its hash value.  */

  /* The memory access itself and associated caching of alias-oracle
     query meta-data.  We are using mem.ref == error_mark_node for the
     case the reference is represented by its single access stmt
     in accesses_in_loop[0].  */
  ao_ref mem;

  bitmap stored;		/* The set of loops in that this memory location
				   is stored to.  */
  bitmap loaded;		/* The set of loops in that this memory location
				   is loaded from.  */
  vec<mem_ref_loc>		accesses_in_loop;
				/* The locations of the accesses.  */

  /* The following set is computed on demand.  */
  bitmap_head dep_loop;		/* The set of loops in that the memory
				   reference is {in,}dependent in
				   different modes.  */
};

/* We use six bits per loop in the ref->dep_loop bitmap to record
   the dep_kind x dep_state combinations.  */

enum dep_kind { lim_raw, sm_war, sm_waw };
enum dep_state { dep_unknown, dep_independent, dep_dependent };

/* coldest outermost loop for given loop.  */
vec<class loop *> coldest_outermost_loop;
/* hotter outer loop nearest to given loop.  */
vec<class loop *> hotter_than_inner_loop;

/* Populate the loop dependence cache of REF for LOOP, KIND with STATE.  */

static void
record_loop_dependence (class loop *loop, im_mem_ref *ref,
			dep_kind kind, dep_state state)
{
  gcc_assert (state != dep_unknown);
  unsigned bit = 6 * loop->num + kind * 2 + state == dep_dependent ? 1 : 0;
  bitmap_set_bit (&ref->dep_loop, bit);
}

/* Query the loop dependence cache of REF for LOOP, KIND.  */

static dep_state
query_loop_dependence (class loop *loop, im_mem_ref *ref, dep_kind kind)
{
  unsigned first_bit = 6 * loop->num + kind * 2;
  if (bitmap_bit_p (&ref->dep_loop, first_bit))
    return dep_independent;
  else if (bitmap_bit_p (&ref->dep_loop, first_bit + 1))
    return dep_dependent;
  return dep_unknown;
}

/* Mem_ref hashtable helpers.  */

struct mem_ref_hasher : nofree_ptr_hash <im_mem_ref>
{
  typedef ao_ref *compare_type;
  static inline hashval_t hash (const im_mem_ref *);
  static inline bool equal (const im_mem_ref *, const ao_ref *);
};

/* A hash function for class im_mem_ref object OBJ.  */

inline hashval_t
mem_ref_hasher::hash (const im_mem_ref *mem)
{
  return mem->hash;
}

/* An equality function for class im_mem_ref object MEM1 with
   memory reference OBJ2.  */

inline bool
mem_ref_hasher::equal (const im_mem_ref *mem1, const ao_ref *obj2)
{
  if (obj2->max_size_known_p ())
    return (mem1->ref_decomposed
	    && ((TREE_CODE (mem1->mem.base) == MEM_REF
		 && TREE_CODE (obj2->base) == MEM_REF
		 && operand_equal_p (TREE_OPERAND (mem1->mem.base, 0),
				     TREE_OPERAND (obj2->base, 0), 0)
		 && known_eq (mem_ref_offset (mem1->mem.base) * BITS_PER_UNIT + mem1->mem.offset,
			      mem_ref_offset (obj2->base) * BITS_PER_UNIT + obj2->offset))
		|| (operand_equal_p (mem1->mem.base, obj2->base, 0)
		    && known_eq (mem1->mem.offset, obj2->offset)))
	    && known_eq (mem1->mem.size, obj2->size)
	    && known_eq (mem1->mem.max_size, obj2->max_size)
	    && mem1->mem.volatile_p == obj2->volatile_p
	    && (mem1->mem.ref_alias_set == obj2->ref_alias_set
		/* We are not canonicalizing alias-sets but for the
		   special-case we didn't canonicalize yet and the
		   incoming ref is a alias-set zero MEM we pick
		   the correct one already.  */
		|| (!mem1->ref_canonical
		    && (TREE_CODE (obj2->ref) == MEM_REF
			|| TREE_CODE (obj2->ref) == TARGET_MEM_REF)
		    && obj2->ref_alias_set == 0)
		/* Likewise if there's a canonical ref with alias-set zero.  */
		|| (mem1->ref_canonical && mem1->mem.ref_alias_set == 0))
	    && types_compatible_p (TREE_TYPE (mem1->mem.ref),
				   TREE_TYPE (obj2->ref)));
  else
    return operand_equal_p (mem1->mem.ref, obj2->ref, 0);
}


/* Description of memory accesses in loops.  */

static struct
{
  /* The hash table of memory references accessed in loops.  */
  hash_table<mem_ref_hasher> *refs;

  /* The list of memory references.  */
  vec<im_mem_ref *> refs_list;

  /* The set of memory references accessed in each loop.  */
  vec<bitmap_head> refs_loaded_in_loop;

  /* The set of memory references stored in each loop.  */
  vec<bitmap_head> refs_stored_in_loop;

  /* The set of memory references stored in each loop, including subloops .  */
  vec<bitmap_head> all_refs_stored_in_loop;

  /* Cache for expanding memory addresses.  */
  hash_map<tree, name_expansion *> *ttae_cache;
} memory_accesses;

/* Obstack for the bitmaps in the above data structures.  */
static bitmap_obstack lim_bitmap_obstack;
static obstack mem_ref_obstack;

static bool ref_indep_loop_p (class loop *, im_mem_ref *, dep_kind);
static bool ref_always_accessed_p (class loop *, im_mem_ref *, bool);
static bool refs_independent_p (im_mem_ref *, im_mem_ref *, bool = true);

/* Minimum cost of an expensive expression.  */
#define LIM_EXPENSIVE ((unsigned) param_lim_expensive)

/* The outermost loop for which execution of the header guarantees that the
   block will be executed.  */
#define ALWAYS_EXECUTED_IN(BB) ((class loop *) (BB)->aux)
#define SET_ALWAYS_EXECUTED_IN(BB, VAL) ((BB)->aux = (void *) (VAL))

/* ID of the shared unanalyzable mem.  */
#define UNANALYZABLE_MEM_ID 0

/* Whether the reference was analyzable.  */
#define MEM_ANALYZABLE(REF) ((REF)->id != UNANALYZABLE_MEM_ID)

static struct lim_aux_data *
init_lim_data (gimple *stmt)
{
  lim_aux_data *p = XCNEW (struct lim_aux_data);
  lim_aux_data_map->put (stmt, p);

  return p;
}

static struct lim_aux_data *
get_lim_data (gimple *stmt)
{
  lim_aux_data **p = lim_aux_data_map->get (stmt);
  if (!p)
    return NULL;

  return *p;
}

/* Releases the memory occupied by DATA.  */

static void
free_lim_aux_data (struct lim_aux_data *data)
{
  data->depends.release ();
  free (data);
}

static void
clear_lim_data (gimple *stmt)
{
  lim_aux_data **p = lim_aux_data_map->get (stmt);
  if (!p)
    return;

  free_lim_aux_data (*p);
  *p = NULL;
}


/* The possibilities of statement movement.  */
enum move_pos
  {
    MOVE_IMPOSSIBLE,		/* No movement -- side effect expression.  */
    MOVE_PRESERVE_EXECUTION,	/* Must not cause the non-executed statement
				   become executed -- memory accesses, ... */
    MOVE_POSSIBLE		/* Unlimited movement.  */
  };


/* If it is possible to hoist the statement STMT unconditionally,
   returns MOVE_POSSIBLE.
   If it is possible to hoist the statement STMT, but we must avoid making
   it executed if it would not be executed in the original program (e.g.
   because it may trap), return MOVE_PRESERVE_EXECUTION.
   Otherwise return MOVE_IMPOSSIBLE.  */

enum move_pos
movement_possibility (gimple *stmt)
{
  tree lhs;
  enum move_pos ret = MOVE_POSSIBLE;

  if (flag_unswitch_loops
      && gimple_code (stmt) == GIMPLE_COND)
    {
      /* If we perform unswitching, force the operands of the invariant
	 condition to be moved out of the loop.  */
      return MOVE_POSSIBLE;
    }

  if (gimple_code (stmt) == GIMPLE_PHI
      && gimple_phi_num_args (stmt) <= 2
      && !virtual_operand_p (gimple_phi_result (stmt))
      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (stmt)))
    return MOVE_POSSIBLE;

  if (gimple_get_lhs (stmt) == NULL_TREE)
    return MOVE_IMPOSSIBLE;

  if (gimple_vdef (stmt))
    return MOVE_IMPOSSIBLE;

  if (stmt_ends_bb_p (stmt)
      || gimple_has_volatile_ops (stmt)
      || gimple_has_side_effects (stmt)
      || stmt_could_throw_p (cfun, stmt))
    return MOVE_IMPOSSIBLE;

  if (is_gimple_call (stmt))
    {
      /* While pure or const call is guaranteed to have no side effects, we
	 cannot move it arbitrarily.  Consider code like

	 char *s = something ();

	 while (1)
	   {
	     if (s)
	       t = strlen (s);
	     else
	       t = 0;
	   }

	 Here the strlen call cannot be moved out of the loop, even though
	 s is invariant.  In addition to possibly creating a call with
	 invalid arguments, moving out a function call that is not executed
	 may cause performance regressions in case the call is costly and
	 not executed at all.  */
      ret = MOVE_PRESERVE_EXECUTION;
      lhs = gimple_call_lhs (stmt);
    }
  else if (is_gimple_assign (stmt))
    lhs = gimple_assign_lhs (stmt);
  else
    return MOVE_IMPOSSIBLE;

  if (TREE_CODE (lhs) == SSA_NAME
      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    return MOVE_IMPOSSIBLE;

  if (TREE_CODE (lhs) != SSA_NAME
      || gimple_could_trap_p (stmt))
    return MOVE_PRESERVE_EXECUTION;

  /* Non local loads in a transaction cannot be hoisted out.  Well,
     unless the load happens on every path out of the loop, but we
     don't take this into account yet.  */
  if (flag_tm
      && gimple_in_transaction (stmt)
      && gimple_assign_single_p (stmt))
    {
      tree rhs = gimple_assign_rhs1 (stmt);
      if (DECL_P (rhs) && is_global_var (rhs))
	{
	  if (dump_file)
	    {
	      fprintf (dump_file, "Cannot hoist conditional load of ");
	      print_generic_expr (dump_file, rhs, TDF_SLIM);
	      fprintf (dump_file, " because it is in a transaction.\n");
	    }
	  return MOVE_IMPOSSIBLE;
	}
    }

  return ret;
}

/* Compare the profile count inequality of bb and loop's preheader, it is
   three-state as stated in profile-count.h, FALSE is returned if inequality
   cannot be decided.  */
bool
bb_colder_than_loop_preheader (basic_block bb, class loop *loop)
{
  gcc_assert (bb && loop);
  return bb->count < loop_preheader_edge (loop)->src->count;
}

/* Check coldest loop between OUTERMOST_LOOP and LOOP by comparing profile
   count.
  It does three steps check:
  1) Check whether CURR_BB is cold in it's own loop_father, if it is cold, just
  return NULL which means it should not be moved out at all;
  2) CURR_BB is NOT cold, check if pre-computed COLDEST_LOOP is outside of
  OUTERMOST_LOOP, if it is inside of OUTERMOST_LOOP, return the COLDEST_LOOP;
  3) If COLDEST_LOOP is outside of OUTERMOST_LOOP, check whether there is a
  hotter loop between OUTERMOST_LOOP and loop in pre-computed
  HOTTER_THAN_INNER_LOOP, return it's nested inner loop, otherwise return
  OUTERMOST_LOOP.
  At last, the coldest_loop is inside of OUTERMOST_LOOP, just return it as
  the hoist target.  */

static class loop *
get_coldest_out_loop (class loop *outermost_loop, class loop *loop,
		      basic_block curr_bb)
{
  gcc_assert (outermost_loop == loop
	      || flow_loop_nested_p (outermost_loop, loop));

  /* If bb_colder_than_loop_preheader returns false due to three-state
    comparision, OUTERMOST_LOOP is returned finally to preserve the behavior.
    Otherwise, return the coldest loop between OUTERMOST_LOOP and LOOP.  */
  if (curr_bb && bb_colder_than_loop_preheader (curr_bb, loop))
    return NULL;

  class loop *coldest_loop = coldest_outermost_loop[loop->num];
  if (loop_depth (coldest_loop) < loop_depth (outermost_loop))
    {
      class loop *hotter_loop = hotter_than_inner_loop[loop->num];
      if (!hotter_loop
	  || loop_depth (hotter_loop) < loop_depth (outermost_loop))
	return outermost_loop;

      /*  hotter_loop is between OUTERMOST_LOOP and LOOP like:
	[loop tree root, ..., coldest_loop, ..., outermost_loop, ...,
	hotter_loop, second_coldest_loop, ..., loop]
	return second_coldest_loop to be the hoist target.  */
      class loop *aloop;
      for (aloop = hotter_loop->inner; aloop; aloop = aloop->next)
	if (aloop == loop || flow_loop_nested_p (aloop, loop))
	  return aloop;
    }
  return coldest_loop;
}

/* Suppose that operand DEF is used inside the LOOP.  Returns the outermost
   loop to that we could move the expression using DEF if it did not have
   other operands, i.e. the outermost loop enclosing LOOP in that the value
   of DEF is invariant.  */

static class loop *
outermost_invariant_loop (tree def, class loop *loop)
{
  gimple *def_stmt;
  basic_block def_bb;
  class loop *max_loop;
  struct lim_aux_data *lim_data;

  if (!def)
    return superloop_at_depth (loop, 1);

  if (TREE_CODE (def) != SSA_NAME)
    {
      gcc_assert (is_gimple_min_invariant (def));
      return superloop_at_depth (loop, 1);
    }

  def_stmt = SSA_NAME_DEF_STMT (def);
  def_bb = gimple_bb (def_stmt);
  if (!def_bb)
    return superloop_at_depth (loop, 1);

  max_loop = find_common_loop (loop, def_bb->loop_father);

  lim_data = get_lim_data (def_stmt);
  if (lim_data != NULL && lim_data->max_loop != NULL)
    max_loop = find_common_loop (max_loop,
				 loop_outer (lim_data->max_loop));
  if (max_loop == loop)
    return NULL;
  max_loop = superloop_at_depth (loop, loop_depth (max_loop) + 1);

  return max_loop;
}

/* DATA is a structure containing information associated with a statement
   inside LOOP.  DEF is one of the operands of this statement.

   Find the outermost loop enclosing LOOP in that value of DEF is invariant
   and record this in DATA->max_loop field.  If DEF itself is defined inside
   this loop as well (i.e. we need to hoist it out of the loop if we want
   to hoist the statement represented by DATA), record the statement in that
   DEF is defined to the DATA->depends list.  Additionally if ADD_COST is true,
   add the cost of the computation of DEF to the DATA->cost.

   If DEF is not invariant in LOOP, return false.  Otherwise return TRUE.  */

static bool
add_dependency (tree def, struct lim_aux_data *data, class loop *loop,
		bool add_cost)
{
  gimple *def_stmt = SSA_NAME_DEF_STMT (def);
  basic_block def_bb = gimple_bb (def_stmt);
  class loop *max_loop;
  struct lim_aux_data *def_data;

  if (!def_bb)
    return true;

  max_loop = outermost_invariant_loop (def, loop);
  if (!max_loop)
    return false;

  if (flow_loop_nested_p (data->max_loop, max_loop))
    data->max_loop = max_loop;

  def_data = get_lim_data (def_stmt);
  if (!def_data)
    return true;

  if (add_cost
      /* Only add the cost if the statement defining DEF is inside LOOP,
	 i.e. if it is likely that by moving the invariants dependent
	 on it, we will be able to avoid creating a new register for
	 it (since it will be only used in these dependent invariants).  */
      && def_bb->loop_father == loop)
    data->cost += def_data->cost;

  data->depends.safe_push (def_stmt);

  return true;
}

/* Returns an estimate for a cost of statement STMT.  The values here
   are just ad-hoc constants, similar to costs for inlining.  */

static unsigned
stmt_cost (gimple *stmt)
{
  /* Always try to create possibilities for unswitching.  */
  if (gimple_code (stmt) == GIMPLE_COND
      || gimple_code (stmt) == GIMPLE_PHI)
    return LIM_EXPENSIVE;

  /* We should be hoisting calls if possible.  */
  if (is_gimple_call (stmt))
    {
      tree fndecl;

      /* Unless the call is a builtin_constant_p; this always folds to a
	 constant, so moving it is useless.  */
      fndecl = gimple_call_fndecl (stmt);
      if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_CONSTANT_P))
	return 0;

      return LIM_EXPENSIVE;
    }

  /* Hoisting memory references out should almost surely be a win.  */
  if (gimple_references_memory_p (stmt))
    return LIM_EXPENSIVE;

  if (gimple_code (stmt) != GIMPLE_ASSIGN)
    return 1;

  switch (gimple_assign_rhs_code (stmt))
    {
    case MULT_EXPR:
    case WIDEN_MULT_EXPR:
    case WIDEN_MULT_PLUS_EXPR:
    case WIDEN_MULT_MINUS_EXPR:
    case DOT_PROD_EXPR:
    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case EXACT_DIV_EXPR:
    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case TRUNC_MOD_EXPR:
    case RDIV_EXPR:
      /* Division and multiplication are usually expensive.  */
      return LIM_EXPENSIVE;

    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case WIDEN_LSHIFT_EXPR:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
      /* Shifts and rotates are usually expensive.  */
      return LIM_EXPENSIVE;

    case CONSTRUCTOR:
      /* Make vector construction cost proportional to the number
         of elements.  */
      return CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));

    case SSA_NAME:
    case PAREN_EXPR:
      /* Whether or not something is wrapped inside a PAREN_EXPR
         should not change move cost.  Nor should an intermediate
	 unpropagated SSA name copy.  */
      return 0;

    default:
      return 1;
    }
}

/* Finds the outermost loop between OUTER and LOOP in that the memory reference
   REF is independent.  If REF is not independent in LOOP, NULL is returned
   instead.  */

static class loop *
outermost_indep_loop (class loop *outer, class loop *loop, im_mem_ref *ref)
{
  class loop *aloop;

  if (ref->stored && bitmap_bit_p (ref->stored, loop->num))
    return NULL;

  for (aloop = outer;
       aloop != loop;
       aloop = superloop_at_depth (loop, loop_depth (aloop) + 1))
    if ((!ref->stored || !bitmap_bit_p (ref->stored, aloop->num))
	&& ref_indep_loop_p (aloop, ref, lim_raw))
      return aloop;

  if (ref_indep_loop_p (loop, ref, lim_raw))
    return loop;
  else
    return NULL;
}

/* If there is a simple load or store to a memory reference in STMT, returns
   the location of the memory reference, and sets IS_STORE according to whether
   it is a store or load.  Otherwise, returns NULL.  */

static tree *
simple_mem_ref_in_stmt (gimple *stmt, bool *is_store)
{
  tree *lhs, *rhs;

  /* Recognize SSA_NAME = MEM and MEM = (SSA_NAME | invariant) patterns.  */
  if (!gimple_assign_single_p (stmt))
    return NULL;

  lhs = gimple_assign_lhs_ptr (stmt);
  rhs = gimple_assign_rhs1_ptr (stmt);

  if (TREE_CODE (*lhs) == SSA_NAME && gimple_vuse (stmt))
    {
      *is_store = false;
      return rhs;
    }
  else if (gimple_vdef (stmt)
	   && (TREE_CODE (*rhs) == SSA_NAME || is_gimple_min_invariant (*rhs)))
    {
      *is_store = true;
      return lhs;
    }
  else
    return NULL;
}

/* From a controlling predicate in DOM determine the arguments from
   the PHI node PHI that are chosen if the predicate evaluates to
   true and false and store them to *TRUE_ARG_P and *FALSE_ARG_P if
   they are non-NULL.  Returns true if the arguments can be determined,
   else return false.  */

static bool
extract_true_false_args_from_phi (basic_block dom, gphi *phi,
				  tree *true_arg_p, tree *false_arg_p)
{
  edge te, fe;
  if (! extract_true_false_controlled_edges (dom, gimple_bb (phi),
					     &te, &fe))
    return false;

  if (true_arg_p)
    *true_arg_p = PHI_ARG_DEF (phi, te->dest_idx);
  if (false_arg_p)
    *false_arg_p = PHI_ARG_DEF (phi, fe->dest_idx);

  return true;
}

/* Determine the outermost loop to that it is possible to hoist a statement
   STMT and store it to LIM_DATA (STMT)->max_loop.  To do this we determine
   the outermost loop in that the value computed by STMT is invariant.
   If MUST_PRESERVE_EXEC is true, additionally choose such a loop that
   we preserve the fact whether STMT is executed.  It also fills other related
   information to LIM_DATA (STMT).

   The function returns false if STMT cannot be hoisted outside of the loop it
   is defined in, and true otherwise.  */

static bool
determine_max_movement (gimple *stmt, bool must_preserve_exec)
{
  basic_block bb = gimple_bb (stmt);
  class loop *loop = bb->loop_father;
  class loop *level;
  struct lim_aux_data *lim_data = get_lim_data (stmt);
  tree val;
  ssa_op_iter iter;

  if (must_preserve_exec)
    level = ALWAYS_EXECUTED_IN (bb);
  else
    level = superloop_at_depth (loop, 1);
  lim_data->max_loop = get_coldest_out_loop (level, loop, bb);
  if (!lim_data->max_loop)
    return false;

  if (gphi *phi = dyn_cast <gphi *> (stmt))
    {
      use_operand_p use_p;
      unsigned min_cost = UINT_MAX;
      unsigned total_cost = 0;
      struct lim_aux_data *def_data;

      /* We will end up promoting dependencies to be unconditionally
	 evaluated.  For this reason the PHI cost (and thus the
	 cost we remove from the loop by doing the invariant motion)
	 is that of the cheapest PHI argument dependency chain.  */
      FOR_EACH_PHI_ARG (use_p, phi, iter, SSA_OP_USE)
	{
	  val = USE_FROM_PTR (use_p);

	  if (TREE_CODE (val) != SSA_NAME)
	    {
	      /* Assign const 1 to constants.  */
	      min_cost = MIN (min_cost, 1);
	      total_cost += 1;
	      continue;
	    }
	  if (!add_dependency (val, lim_data, loop, false))
	    return false;

	  gimple *def_stmt = SSA_NAME_DEF_STMT (val);
	  if (gimple_bb (def_stmt)
	      && gimple_bb (def_stmt)->loop_father == loop)
	    {
	      def_data = get_lim_data (def_stmt);
	      if (def_data)
		{
		  min_cost = MIN (min_cost, def_data->cost);
		  total_cost += def_data->cost;
		}
	    }
	}

      min_cost = MIN (min_cost, total_cost);
      lim_data->cost += min_cost;

      if (gimple_phi_num_args (phi) > 1)
	{
	  basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb);
	  gimple *cond;
	  if (gsi_end_p (gsi_last_bb (dom)))
	    return false;
	  cond = gsi_stmt (gsi_last_bb (dom));
	  if (gimple_code (cond) != GIMPLE_COND)
	    return false;
	  /* Verify that this is an extended form of a diamond and
	     the PHI arguments are completely controlled by the
	     predicate in DOM.  */
	  if (!extract_true_false_args_from_phi (dom, phi, NULL, NULL))
	    return false;

	  /* Fold in dependencies and cost of the condition.  */
	  FOR_EACH_SSA_TREE_OPERAND (val, cond, iter, SSA_OP_USE)
	    {
	      if (!add_dependency (val, lim_data, loop, false))
		return false;
	      def_data = get_lim_data (SSA_NAME_DEF_STMT (val));
	      if (def_data)
		lim_data->cost += def_data->cost;
	    }

	  /* We want to avoid unconditionally executing very expensive
	     operations.  As costs for our dependencies cannot be
	     negative just claim we are not invariand for this case.
	     We also are not sure whether the control-flow inside the
	     loop will vanish.  */
	  if (total_cost - min_cost >= 2 * LIM_EXPENSIVE
	      && !(min_cost != 0
		   && total_cost / min_cost <= 2))
	    return false;

	  /* Assume that the control-flow in the loop will vanish.
	     ???  We should verify this and not artificially increase
	     the cost if that is not the case.  */
	  lim_data->cost += stmt_cost (stmt);
	}

      return true;
    }

  /* A stmt that receives abnormal edges cannot be hoisted.  */
  if (is_a <gcall *> (stmt)
      && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE))
    return false;

  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_USE)
    if (!add_dependency (val, lim_data, loop, true))
      return false;

  if (gimple_vuse (stmt))
    {
      im_mem_ref *ref
	= lim_data ? memory_accesses.refs_list[lim_data->ref] : NULL;
      if (ref
	  && MEM_ANALYZABLE (ref))
	{
	  lim_data->max_loop = outermost_indep_loop (lim_data->max_loop,
						     loop, ref);
	  if (!lim_data->max_loop)
	    return false;
	}
      else if (! add_dependency (gimple_vuse (stmt), lim_data, loop, false))
	return false;
    }

  lim_data->cost += stmt_cost (stmt);

  return true;
}

/* Suppose that some statement in ORIG_LOOP is hoisted to the loop LEVEL,
   and that one of the operands of this statement is computed by STMT.
   Ensure that STMT (together with all the statements that define its
   operands) is hoisted at least out of the loop LEVEL.  */

static void
set_level (gimple *stmt, class loop *orig_loop, class loop *level)
{
  class loop *stmt_loop = gimple_bb (stmt)->loop_father;
  struct lim_aux_data *lim_data;
  gimple *dep_stmt;
  unsigned i;

  stmt_loop = find_common_loop (orig_loop, stmt_loop);
  lim_data = get_lim_data (stmt);
  if (lim_data != NULL && lim_data->tgt_loop != NULL)
    stmt_loop = find_common_loop (stmt_loop,
				  loop_outer (lim_data->tgt_loop));
  if (flow_loop_nested_p (stmt_loop, level))
    return;

  gcc_assert (level == lim_data->max_loop
	      || flow_loop_nested_p (lim_data->max_loop, level));

  lim_data->tgt_loop = level;
  FOR_EACH_VEC_ELT (lim_data->depends, i, dep_stmt)
    set_level (dep_stmt, orig_loop, level);
}

/* Determines an outermost loop from that we want to hoist the statement STMT.
   For now we chose the outermost possible loop.  TODO -- use profiling
   information to set it more sanely.  */

static void
set_profitable_level (gimple *stmt)
{
  set_level (stmt, gimple_bb (stmt)->loop_father, get_lim_data (stmt)->max_loop);
}

/* Returns true if STMT is a call that has side effects.  */

static bool
nonpure_call_p (gimple *stmt)
{
  if (gimple_code (stmt) != GIMPLE_CALL)
    return false;

  return gimple_has_side_effects (stmt);
}

/* Rewrite a/b to a*(1/b).  Return the invariant stmt to process.  */

static gimple *
rewrite_reciprocal (gimple_stmt_iterator *bsi)
{
  gassign *stmt, *stmt1, *stmt2;
  tree name, lhs, type;
  tree real_one;
  gimple_stmt_iterator gsi;

  stmt = as_a <gassign *> (gsi_stmt (*bsi));
  lhs = gimple_assign_lhs (stmt);
  type = TREE_TYPE (lhs);

  real_one = build_one_cst (type);

  name = make_temp_ssa_name (type, NULL, "reciptmp");
  stmt1 = gimple_build_assign (name, RDIV_EXPR, real_one,
			       gimple_assign_rhs2 (stmt));
  stmt2 = gimple_build_assign (lhs, MULT_EXPR, name,
			       gimple_assign_rhs1 (stmt));

  /* Replace division stmt with reciprocal and multiply stmts.
     The multiply stmt is not invariant, so update iterator
     and avoid rescanning.  */
  gsi = *bsi;
  gsi_insert_before (bsi, stmt1, GSI_NEW_STMT);
  gsi_replace (&gsi, stmt2, true);

  /* Continue processing with invariant reciprocal statement.  */
  return stmt1;
}

/* Check if the pattern at *BSI is a bittest of the form
   (A >> B) & 1 != 0 and in this case rewrite it to A & (1 << B) != 0.  */

static gimple *
rewrite_bittest (gimple_stmt_iterator *bsi)
{
  gassign *stmt;
  gimple *stmt1;
  gassign *stmt2;
  gimple *use_stmt;
  gcond *cond_stmt;
  tree lhs, name, t, a, b;
  use_operand_p use;

  stmt = as_a <gassign *> (gsi_stmt (*bsi));
  lhs = gimple_assign_lhs (stmt);

  /* Verify that the single use of lhs is a comparison against zero.  */
  if (TREE_CODE (lhs) != SSA_NAME
      || !single_imm_use (lhs, &use, &use_stmt))
    return stmt;
  cond_stmt = dyn_cast <gcond *> (use_stmt);
  if (!cond_stmt)
    return stmt;
  if (gimple_cond_lhs (cond_stmt) != lhs
      || (gimple_cond_code (cond_stmt) != NE_EXPR
	  && gimple_cond_code (cond_stmt) != EQ_EXPR)
      || !integer_zerop (gimple_cond_rhs (cond_stmt)))
    return stmt;

  /* Get at the operands of the shift.  The rhs is TMP1 & 1.  */
  stmt1 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
  if (gimple_code (stmt1) != GIMPLE_ASSIGN)
    return stmt;

  /* There is a conversion in between possibly inserted by fold.  */
  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt1)))
    {
      t = gimple_assign_rhs1 (stmt1);
      if (TREE_CODE (t) != SSA_NAME
	  || !has_single_use (t))
	return stmt;
      stmt1 = SSA_NAME_DEF_STMT (t);
      if (gimple_code (stmt1) != GIMPLE_ASSIGN)
	return stmt;
    }

  /* Verify that B is loop invariant but A is not.  Verify that with
     all the stmt walking we are still in the same loop.  */
  if (gimple_assign_rhs_code (stmt1) != RSHIFT_EXPR
      || loop_containing_stmt (stmt1) != loop_containing_stmt (stmt))
    return stmt;

  a = gimple_assign_rhs1 (stmt1);
  b = gimple_assign_rhs2 (stmt1);

  if (outermost_invariant_loop (b, loop_containing_stmt (stmt1)) != NULL
      && outermost_invariant_loop (a, loop_containing_stmt (stmt1)) == NULL)
    {
      gimple_stmt_iterator rsi;

      /* 1 << B */
      t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (a),
		       build_int_cst (TREE_TYPE (a), 1), b);
      name = make_temp_ssa_name (TREE_TYPE (a), NULL, "shifttmp");
      stmt1 = gimple_build_assign (name, t);

      /* A & (1 << B) */
      t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (a), a, name);
      name = make_temp_ssa_name (TREE_TYPE (a), NULL, "shifttmp");
      stmt2 = gimple_build_assign (name, t);

      /* Replace the SSA_NAME we compare against zero.  Adjust
	 the type of zero accordingly.  */
      SET_USE (use, name);
      gimple_cond_set_rhs (cond_stmt,
			   build_int_cst_type (TREE_TYPE (name),
					       0));

      /* Don't use gsi_replace here, none of the new assignments sets
	 the variable originally set in stmt.  Move bsi to stmt1, and
	 then remove the original stmt, so that we get a chance to
	 retain debug info for it.  */
      rsi = *bsi;
      gsi_insert_before (bsi, stmt1, GSI_NEW_STMT);
      gsi_insert_before (&rsi, stmt2, GSI_SAME_STMT);
      gimple *to_release = gsi_stmt (rsi);
      gsi_remove (&rsi, true);
      release_defs (to_release);

      return stmt1;
    }

  return stmt;
}

/* Determine the outermost loops in that statements in basic block BB are
   invariant, and record them to the LIM_DATA associated with the
   statements.  */

static void
compute_invariantness (basic_block bb)
{
  enum move_pos pos;
  gimple_stmt_iterator bsi;
  gimple *stmt;
  bool maybe_never = ALWAYS_EXECUTED_IN (bb) == NULL;
  class loop *outermost = ALWAYS_EXECUTED_IN (bb);
  struct lim_aux_data *lim_data;

  if (!loop_outer (bb->loop_father))
    return;

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Basic block %d (loop %d -- depth %d):\n\n",
	     bb->index, bb->loop_father->num, loop_depth (bb->loop_father));

  /* Look at PHI nodes, but only if there is at most two.
     ???  We could relax this further by post-processing the inserted
     code and transforming adjacent cond-exprs with the same predicate
     to control flow again.  */
  bsi = gsi_start_phis (bb);
  if (!gsi_end_p (bsi)
      && ((gsi_next (&bsi), gsi_end_p (bsi))
	  || (gsi_next (&bsi), gsi_end_p (bsi))))
    for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
      {
	stmt = gsi_stmt (bsi);

	pos = movement_possibility (stmt);
	if (pos == MOVE_IMPOSSIBLE)
	  continue;

	lim_data = get_lim_data (stmt);
	if (! lim_data)
	  lim_data = init_lim_data (stmt);
	lim_data->always_executed_in = outermost;

	if (!determine_max_movement (stmt, false))
	  {
	    lim_data->max_loop = NULL;
	    continue;
	  }

	if (dump_file && (dump_flags & TDF_DETAILS))
	  {
	    print_gimple_stmt (dump_file, stmt, 2);
	    fprintf (dump_file, "  invariant up to level %d, cost %d.\n\n",
		     loop_depth (lim_data->max_loop),
		     lim_data->cost);
	  }

	if (lim_data->cost >= LIM_EXPENSIVE)
	  set_profitable_level (stmt);
      }

  for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
    {
      stmt = gsi_stmt (bsi);

      pos = movement_possibility (stmt);
      if (pos == MOVE_IMPOSSIBLE)
	{
	  if (nonpure_call_p (stmt))
	    {
	      maybe_never = true;
	      outermost = NULL;
	    }
	  /* Make sure to note always_executed_in for stores to make
	     store-motion work.  */
	  else if (stmt_makes_single_store (stmt))
	    {
	      struct lim_aux_data *lim_data = get_lim_data (stmt);
	      if (! lim_data)
		lim_data = init_lim_data (stmt);
	      lim_data->always_executed_in = outermost;
	    }
	  continue;
	}

      if (is_gimple_assign (stmt)
	  && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
	      == GIMPLE_BINARY_RHS))
	{
	  tree op0 = gimple_assign_rhs1 (stmt);
	  tree op1 = gimple_assign_rhs2 (stmt);
	  class loop *ol1 = outermost_invariant_loop (op1,
					loop_containing_stmt (stmt));

	  /* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal
	     to be hoisted out of loop, saving expensive divide.  */
	  if (pos == MOVE_POSSIBLE
	      && gimple_assign_rhs_code (stmt) == RDIV_EXPR
	      && flag_unsafe_math_optimizations
	      && !flag_trapping_math
	      && ol1 != NULL
	      && outermost_invariant_loop (op0, ol1) == NULL)
	    stmt = rewrite_reciprocal (&bsi);

	  /* If the shift count is invariant, convert (A >> B) & 1 to
	     A & (1 << B) allowing the bit mask to be hoisted out of the loop
	     saving an expensive shift.  */
	  if (pos == MOVE_POSSIBLE
	      && gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
	      && integer_onep (op1)
	      && TREE_CODE (op0) == SSA_NAME
	      && has_single_use (op0))
	    stmt = rewrite_bittest (&bsi);
	}

      lim_data = get_lim_data (stmt);
      if (! lim_data)
	lim_data = init_lim_data (stmt);
      lim_data->always_executed_in = outermost;

      if (maybe_never && pos == MOVE_PRESERVE_EXECUTION)
	continue;

      if (!determine_max_movement (stmt, pos == MOVE_PRESERVE_EXECUTION))
	{
	  lim_data->max_loop = NULL;
	  continue;
	}

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  print_gimple_stmt (dump_file, stmt, 2);
	  fprintf (dump_file, "  invariant up to level %d, cost %d.\n\n",
		   loop_depth (lim_data->max_loop),
		   lim_data->cost);
	}

      if (lim_data->cost >= LIM_EXPENSIVE)
	set_profitable_level (stmt);
    }
}

/* Hoist the statements in basic block BB out of the loops prescribed by
   data stored in LIM_DATA structures associated with each statement.  Callback
   for walk_dominator_tree.  */

unsigned int
move_computations_worker (basic_block bb)
{
  class loop *level;
  unsigned cost = 0;
  struct lim_aux_data *lim_data;
  unsigned int todo = 0;

  if (!loop_outer (bb->loop_father))
    return todo;

  for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi); )
    {
      gassign *new_stmt;
      gphi *stmt = bsi.phi ();

      lim_data = get_lim_data (stmt);
      if (lim_data == NULL)
	{
	  gsi_next (&bsi);
	  continue;
	}

      cost = lim_data->cost;
      level = lim_data->tgt_loop;
      clear_lim_data (stmt);

      if (!level)
	{
	  gsi_next (&bsi);
	  continue;
	}

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Moving PHI node\n");
	  print_gimple_stmt (dump_file, stmt, 0);
	  fprintf (dump_file, "(cost %u) out of loop %d.\n\n",
		   cost, level->num);
	}

      if (gimple_phi_num_args (stmt) == 1)
	{
	  tree arg = PHI_ARG_DEF (stmt, 0);
	  new_stmt = gimple_build_assign (gimple_phi_result (stmt),
					  TREE_CODE (arg), arg);
	}
      else
	{
	  basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb);
	  gimple *cond = gsi_stmt (gsi_last_bb (dom));
	  tree arg0 = NULL_TREE, arg1 = NULL_TREE, t;
	  /* Get the PHI arguments corresponding to the true and false
	     edges of COND.  */
	  extract_true_false_args_from_phi (dom, stmt, &arg0, &arg1);
	  gcc_assert (arg0 && arg1);
	  t = make_ssa_name (boolean_type_node);
	  new_stmt = gimple_build_assign (t, gimple_cond_code (cond),
					  gimple_cond_lhs (cond),
					  gimple_cond_rhs (cond));
	  gsi_insert_on_edge (loop_preheader_edge (level), new_stmt);
	  new_stmt = gimple_build_assign (gimple_phi_result (stmt),
					  COND_EXPR, t, arg0, arg1);
	  todo |= TODO_cleanup_cfg;
	}
      if (!ALWAYS_EXECUTED_IN (bb)
	  || (ALWAYS_EXECUTED_IN (bb) != level
	      && !flow_loop_nested_p (ALWAYS_EXECUTED_IN (bb), level)))
	reset_flow_sensitive_info (gimple_assign_lhs (new_stmt));
      gsi_insert_on_edge (loop_preheader_edge (level), new_stmt);
      remove_phi_node (&bsi, false);
    }

  for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi); )
    {
      edge e;

      gimple *stmt = gsi_stmt (bsi);

      lim_data = get_lim_data (stmt);
      if (lim_data == NULL)
	{
	  gsi_next (&bsi);
	  continue;
	}

      cost = lim_data->cost;
      level = lim_data->tgt_loop;
      clear_lim_data (stmt);

      if (!level)
	{
	  gsi_next (&bsi);
	  continue;
	}

      /* We do not really want to move conditionals out of the loop; we just
	 placed it here to force its operands to be moved if necessary.  */
      if (gimple_code (stmt) == GIMPLE_COND)
	{
	  gsi_next (&bsi);
	  continue;
	}

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Moving statement\n");
	  print_gimple_stmt (dump_file, stmt, 0);
	  fprintf (dump_file, "(cost %u) out of loop %d.\n\n",
		   cost, level->num);
	}

      e = loop_preheader_edge (level);
      gcc_assert (!gimple_vdef (stmt));
      if (gimple_vuse (stmt))
	{
	  /* The new VUSE is the one from the virtual PHI in the loop
	     header or the one already present.  */
	  gphi_iterator gsi2;
	  for (gsi2 = gsi_start_phis (e->dest);
	       !gsi_end_p (gsi2); gsi_next (&gsi2))
	    {
	      gphi *phi = gsi2.phi ();
	      if (virtual_operand_p (gimple_phi_result (phi)))
		{
		  SET_USE (gimple_vuse_op (stmt),
			   PHI_ARG_DEF_FROM_EDGE (phi, e));
		  break;
		}
	    }
	}
      gsi_remove (&bsi, false);
      if (gimple_has_lhs (stmt)
	  && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
	  && (!ALWAYS_EXECUTED_IN (bb)
	      || !(ALWAYS_EXECUTED_IN (bb) == level
		   || flow_loop_nested_p (ALWAYS_EXECUTED_IN (bb), level))))
	reset_flow_sensitive_info (gimple_get_lhs (stmt));
      /* In case this is a stmt that is not unconditionally executed
         when the target loop header is executed and the stmt may
	 invoke undefined integer or pointer overflow rewrite it to
	 unsigned arithmetic.  */
      if (is_gimple_assign (stmt)
	  && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
	  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (gimple_assign_lhs (stmt)))
	  && arith_code_with_undefined_signed_overflow
	       (gimple_assign_rhs_code (stmt))
	  && (!ALWAYS_EXECUTED_IN (bb)
	      || !(ALWAYS_EXECUTED_IN (bb) == level
		   || flow_loop_nested_p (ALWAYS_EXECUTED_IN (bb), level))))
	gsi_insert_seq_on_edge (e, rewrite_to_defined_overflow (stmt));
      else
	gsi_insert_on_edge (e, stmt);
    }

  return todo;
}

/* Checks whether the statement defining variable *INDEX can be hoisted
   out of the loop passed in DATA.  Callback for for_each_index.  */

static bool
may_move_till (tree ref, tree *index, void *data)
{
  class loop *loop = (class loop *) data, *max_loop;

  /* If REF is an array reference, check also that the step and the lower
     bound is invariant in LOOP.  */
  if (TREE_CODE (ref) == ARRAY_REF)
    {
      tree step = TREE_OPERAND (ref, 3);
      tree lbound = TREE_OPERAND (ref, 2);

      max_loop = outermost_invariant_loop (step, loop);
      if (!max_loop)
	return false;

      max_loop = outermost_invariant_loop (lbound, loop);
      if (!max_loop)
	return false;
    }

  max_loop = outermost_invariant_loop (*index, loop);
  if (!max_loop)
    return false;

  return true;
}

/* If OP is SSA NAME, force the statement that defines it to be
   moved out of the LOOP.  ORIG_LOOP is the loop in that EXPR is used.  */

static void
force_move_till_op (tree op, class loop *orig_loop, class loop *loop)
{
  gimple *stmt;

  if (!op
      || is_gimple_min_invariant (op))
    return;

  gcc_assert (TREE_CODE (op) == SSA_NAME);

  stmt = SSA_NAME_DEF_STMT (op);
  if (gimple_nop_p (stmt))
    return;

  set_level (stmt, orig_loop, loop);
}

/* Forces statement defining invariants in REF (and *INDEX) to be moved out of
   the LOOP.  The reference REF is used in the loop ORIG_LOOP.  Callback for
   for_each_index.  */

struct fmt_data
{
  class loop *loop;
  class loop *orig_loop;
};

static bool
force_move_till (tree ref, tree *index, void *data)
{
  struct fmt_data *fmt_data = (struct fmt_data *) data;

  if (TREE_CODE (ref) == ARRAY_REF)
    {
      tree step = TREE_OPERAND (ref, 3);
      tree lbound = TREE_OPERAND (ref, 2);

      force_move_till_op (step, fmt_data->orig_loop, fmt_data->loop);
      force_move_till_op (lbound, fmt_data->orig_loop, fmt_data->loop);
    }

  force_move_till_op (*index, fmt_data->orig_loop, fmt_data->loop);

  return true;
}

/* A function to free the mem_ref object OBJ.  */

static void
memref_free (class im_mem_ref *mem)
{
  mem->accesses_in_loop.release ();
}

/* Allocates and returns a memory reference description for MEM whose hash
   value is HASH and id is ID.  */

static im_mem_ref *
mem_ref_alloc (ao_ref *mem, unsigned hash, unsigned id)
{
  im_mem_ref *ref = XOBNEW (&mem_ref_obstack, class im_mem_ref);
  if (mem)
    ref->mem = *mem;
  else
    ao_ref_init (&ref->mem, error_mark_node);
  ref->id = id;
  ref->ref_canonical = false;
  ref->ref_decomposed = false;
  ref->hash = hash;
  ref->stored = NULL;
  ref->loaded = NULL;
  bitmap_initialize (&ref->dep_loop, &lim_bitmap_obstack);
  ref->accesses_in_loop.create (1);

  return ref;
}

/* Records memory reference location *LOC in LOOP to the memory reference
   description REF.  The reference occurs in statement STMT.  */

static void
record_mem_ref_loc (im_mem_ref *ref, gimple *stmt, tree *loc)
{
  mem_ref_loc aref;
  aref.stmt = stmt;
  aref.ref = loc;
  ref->accesses_in_loop.safe_push (aref);
}

/* Set the LOOP bit in REF stored bitmap and allocate that if
   necessary.  Return whether a bit was changed.  */

static bool
set_ref_stored_in_loop (im_mem_ref *ref, class loop *loop)
{
  if (!ref->stored)
    ref->stored = BITMAP_ALLOC (&lim_bitmap_obstack);
  return bitmap_set_bit (ref->stored, loop->num);
}

/* Marks reference REF as stored in LOOP.  */

static void
mark_ref_stored (im_mem_ref *ref, class loop *loop)
{
  while (loop != current_loops->tree_root
	 && set_ref_stored_in_loop (ref, loop))
    loop = loop_outer (loop);
}

/* Set the LOOP bit in REF loaded bitmap and allocate that if
   necessary.  Return whether a bit was changed.  */

static bool
set_ref_loaded_in_loop (im_mem_ref *ref, class loop *loop)
{
  if (!ref->loaded)
    ref->loaded = BITMAP_ALLOC (&lim_bitmap_obstack);
  return bitmap_set_bit (ref->loaded, loop->num);
}

/* Marks reference REF as loaded in LOOP.  */

static void
mark_ref_loaded (im_mem_ref *ref, class loop *loop)
{
  while (loop != current_loops->tree_root
	 && set_ref_loaded_in_loop (ref, loop))
    loop = loop_outer (loop);
}

/* Gathers memory references in statement STMT in LOOP, storing the
   information about them in the memory_accesses structure.  Marks
   the vops accessed through unrecognized statements there as
   well.  */

static void
gather_mem_refs_stmt (class loop *loop, gimple *stmt)
{
  tree *mem = NULL;
  hashval_t hash;
  im_mem_ref **slot;
  im_mem_ref *ref;
  bool is_stored;
  unsigned id;

  if (!gimple_vuse (stmt))
    return;

  mem = simple_mem_ref_in_stmt (stmt, &is_stored);
  if (!mem && is_gimple_assign (stmt))
    {
      /* For aggregate copies record distinct references but use them
	 only for disambiguation purposes.  */
      id = memory_accesses.refs_list.length ();
      ref = mem_ref_alloc (NULL, 0, id);
      memory_accesses.refs_list.safe_push (ref);
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Unhandled memory reference %u: ", id);
	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	}
      record_mem_ref_loc (ref, stmt, mem);
      is_stored = gimple_vdef (stmt);
    }
  else if (!mem)
    {
      /* We use the shared mem_ref for all unanalyzable refs.  */
      id = UNANALYZABLE_MEM_ID;
      ref = memory_accesses.refs_list[id];
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Unanalyzed memory reference %u: ", id);
	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	}
      is_stored = gimple_vdef (stmt);
    }
  else
    {
      /* We are looking for equal refs that might differ in structure
         such as a.b vs. MEM[&a + 4].  So we key off the ao_ref but
	 make sure we can canonicalize the ref in the hashtable if
	 non-operand_equal_p refs are found.  For the lookup we mark
	 the case we want strict equality with aor.max_size == -1.  */
      ao_ref aor;
      ao_ref_init (&aor, *mem);
      ao_ref_base (&aor);
      ao_ref_alias_set (&aor);
      HOST_WIDE_INT offset, size, max_size;
      poly_int64 saved_maxsize = aor.max_size, mem_off;
      tree mem_base;
      bool ref_decomposed;
      if (aor.max_size_known_p ()
	  && aor.offset.is_constant (&offset)
	  && aor.size.is_constant (&size)
	  && aor.max_size.is_constant (&max_size)
	  && size == max_size
	  && (size % BITS_PER_UNIT) == 0
	  /* We're canonicalizing to a MEM where TYPE_SIZE specifies the
	     size.  Make sure this is consistent with the extraction.  */
	  && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (*mem)))
	  && known_eq (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (*mem))),
		       aor.size)
	  && (mem_base = get_addr_base_and_unit_offset (aor.ref, &mem_off)))
	{
	  ref_decomposed = true;
	  tree base = ao_ref_base (&aor);
	  poly_int64 moffset;
	  HOST_WIDE_INT mcoffset;
	  if (TREE_CODE (base) == MEM_REF
	      && (mem_ref_offset (base) * BITS_PER_UNIT + offset).to_shwi (&moffset)
	      && moffset.is_constant (&mcoffset))
	    {
	      hash = iterative_hash_expr (TREE_OPERAND (base, 0), 0);
	      hash = iterative_hash_host_wide_int (mcoffset, hash);
	    }
	  else
	    {
	      hash = iterative_hash_expr (base, 0);
	      hash = iterative_hash_host_wide_int (offset, hash);
	    }
	  hash = iterative_hash_host_wide_int (size, hash);
	}
      else
	{
	  ref_decomposed = false;
	  hash = iterative_hash_expr (aor.ref, 0);
	  aor.max_size = -1;
	}
      slot = memory_accesses.refs->find_slot_with_hash (&aor, hash, INSERT);
      aor.max_size = saved_maxsize;
      if (*slot)
	{
	  if (!(*slot)->ref_canonical 
	      && !operand_equal_p (*mem, (*slot)->mem.ref, 0))
	    {
	      /* If we didn't yet canonicalize the hashtable ref (which
	         we'll end up using for code insertion) and hit a second
		 equal ref that is not structurally equivalent create
		 a canonical ref which is a bare MEM_REF.  */
	      if (TREE_CODE (*mem) == MEM_REF
		  || TREE_CODE (*mem) == TARGET_MEM_REF)
		{
		  (*slot)->mem.ref = *mem;
		  (*slot)->mem.base_alias_set = ao_ref_base_alias_set (&aor);
		}
	      else
		{
		  tree ref_alias_type = reference_alias_ptr_type (*mem);
		  unsigned int ref_align = get_object_alignment (*mem);
		  tree ref_type = TREE_TYPE (*mem);
		  tree tmp = build1 (ADDR_EXPR, ptr_type_node,
				     unshare_expr (mem_base));
		  if (TYPE_ALIGN (ref_type) != ref_align)
		    ref_type = build_aligned_type (ref_type, ref_align);
		  (*slot)->mem.ref
		    = fold_build2 (MEM_REF, ref_type, tmp,
				   build_int_cst (ref_alias_type, mem_off));
		  if ((*slot)->mem.volatile_p)
		    TREE_THIS_VOLATILE ((*slot)->mem.ref) = 1;
		  gcc_checking_assert (TREE_CODE ((*slot)->mem.ref) == MEM_REF
				       && is_gimple_mem_ref_addr
				            (TREE_OPERAND ((*slot)->mem.ref,
							   0)));
		  (*slot)->mem.base_alias_set = (*slot)->mem.ref_alias_set;
		}
	      (*slot)->ref_canonical = true;
	    }
	  ref = *slot;
	  id = ref->id;
	}
      else
	{
	  id = memory_accesses.refs_list.length ();
	  ref = mem_ref_alloc (&aor, hash, id);
	  ref->ref_decomposed = ref_decomposed;
	  memory_accesses.refs_list.safe_push (ref);
	  *slot = ref;

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Memory reference %u: ", id);
	      print_generic_expr (dump_file, ref->mem.ref, TDF_SLIM);
	      fprintf (dump_file, "\n");
	    }
	}

      record_mem_ref_loc (ref, stmt, mem);
    }
  if (is_stored)
    {
      bitmap_set_bit (&memory_accesses.refs_stored_in_loop[loop->num], ref->id);
      mark_ref_stored (ref, loop);
    }
  /* A not simple memory op is also a read when it is a write.  */
  if (!is_stored || id == UNANALYZABLE_MEM_ID
      || ref->mem.ref == error_mark_node)
    {
      bitmap_set_bit (&memory_accesses.refs_loaded_in_loop[loop->num], ref->id);
      mark_ref_loaded (ref, loop);
    }
  init_lim_data (stmt)->ref = ref->id;
  return;
}

static unsigned *bb_loop_postorder;

/* qsort sort function to sort blocks after their loop fathers postorder.  */

static int
sort_bbs_in_loop_postorder_cmp (const void *bb1_, const void *bb2_,
				void *bb_loop_postorder_)
{
  unsigned *bb_loop_postorder = (unsigned *)bb_loop_postorder_;
  basic_block bb1 = *(const basic_block *)bb1_;
  basic_block bb2 = *(const basic_block *)bb2_;
  class loop *loop1 = bb1->loop_father;
  class loop *loop2 = bb2->loop_father;
  if (loop1->num == loop2->num)
    return bb1->index - bb2->index;
  return bb_loop_postorder[loop1->num] < bb_loop_postorder[loop2->num] ? -1 : 1;
}

/* qsort sort function to sort ref locs after their loop fathers postorder.  */

static int
sort_locs_in_loop_postorder_cmp (const void *loc1_, const void *loc2_,
				 void *bb_loop_postorder_)
{
  unsigned *bb_loop_postorder = (unsigned *)bb_loop_postorder_;
  const mem_ref_loc *loc1 = (const mem_ref_loc *)loc1_;
  const mem_ref_loc *loc2 = (const mem_ref_loc *)loc2_;
  class loop *loop1 = gimple_bb (loc1->stmt)->loop_father;
  class loop *loop2 = gimple_bb (loc2->stmt)->loop_father;
  if (loop1->num == loop2->num)
    return 0;
  return bb_loop_postorder[loop1->num] < bb_loop_postorder[loop2->num] ? -1 : 1;
}

/* Gathers memory references in loops.  */

static void
analyze_memory_references (bool store_motion)
{
  gimple_stmt_iterator bsi;
  basic_block bb, *bbs;
  class loop *outer;
  unsigned i, n;

  /* Collect all basic-blocks in loops and sort them after their
     loops postorder.  */
  i = 0;
  bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS);
  FOR_EACH_BB_FN (bb, cfun)
    if (bb->loop_father != current_loops->tree_root)
      bbs[i++] = bb;
  n = i;
  gcc_sort_r (bbs, n, sizeof (basic_block), sort_bbs_in_loop_postorder_cmp,
	      bb_loop_postorder);

  /* Visit blocks in loop postorder and assign mem-ref IDs in that order.
     That results in better locality for all the bitmaps.  It also
     automatically sorts the location list of gathered memory references
     after their loop postorder number allowing to binary-search it.  */
  for (i = 0; i < n; ++i)
    {
      basic_block bb = bbs[i];
      for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
        gather_mem_refs_stmt (bb->loop_father, gsi_stmt (bsi));
    }

  /* Verify the list of gathered memory references is sorted after their
     loop postorder number.  */
  if (flag_checking)
    {
      im_mem_ref *ref;
      FOR_EACH_VEC_ELT (memory_accesses.refs_list, i, ref)
	for (unsigned j = 1; j < ref->accesses_in_loop.length (); ++j)
	  gcc_assert (sort_locs_in_loop_postorder_cmp
			(&ref->accesses_in_loop[j-1], &ref->accesses_in_loop[j],
			 bb_loop_postorder) <= 0);
    }

  free (bbs);

  if (!store_motion)
    return;

  /* Propagate the information about accessed memory references up
     the loop hierarchy.  */
  for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
    {
      /* Finalize the overall touched references (including subloops).  */
      bitmap_ior_into (&memory_accesses.all_refs_stored_in_loop[loop->num],
		       &memory_accesses.refs_stored_in_loop[loop->num]);

      /* Propagate the information about accessed memory references up
	 the loop hierarchy.  */
      outer = loop_outer (loop);
      if (outer == current_loops->tree_root)
	continue;

      bitmap_ior_into (&memory_accesses.all_refs_stored_in_loop[outer->num],
		       &memory_accesses.all_refs_stored_in_loop[loop->num]);
    }
}

/* Returns true if MEM1 and MEM2 may alias.  TTAE_CACHE is used as a cache in
   tree_to_aff_combination_expand.  */

static bool
mem_refs_may_alias_p (im_mem_ref *mem1, im_mem_ref *mem2,
		      hash_map<tree, name_expansion *> **ttae_cache,
		      bool tbaa_p)
{
  gcc_checking_assert (mem1->mem.ref != error_mark_node
		       && mem2->mem.ref != error_mark_node);

  /* Perform BASE + OFFSET analysis -- if MEM1 and MEM2 are based on the same
     object and their offset differ in such a way that the locations cannot
     overlap, then they cannot alias.  */
  poly_widest_int size1, size2;
  aff_tree off1, off2;

  /* Perform basic offset and type-based disambiguation.  */
  if (!refs_may_alias_p_1 (&mem1->mem, &mem2->mem, tbaa_p))
    return false;

  /* The expansion of addresses may be a bit expensive, thus we only do
     the check at -O2 and higher optimization levels.  */
  if (optimize < 2)
    return true;

  get_inner_reference_aff (mem1->mem.ref, &off1, &size1);
  get_inner_reference_aff (mem2->mem.ref, &off2, &size2);
  aff_combination_expand (&off1, ttae_cache);
  aff_combination_expand (&off2, ttae_cache);
  aff_combination_scale (&off1, -1);
  aff_combination_add (&off2, &off1);

  if (aff_comb_cannot_overlap_p (&off2, size1, size2))
    return false;

  return true;
}

/* Compare function for bsearch searching for reference locations
   in a loop.  */

static int
find_ref_loc_in_loop_cmp (const void *loop_, const void *loc_,
			  void *bb_loop_postorder_)
{
  unsigned *bb_loop_postorder = (unsigned *)bb_loop_postorder_;
  class loop *loop = (class loop *)const_cast<void *>(loop_);
  mem_ref_loc *loc = (mem_ref_loc *)const_cast<void *>(loc_);
  class loop *loc_loop = gimple_bb (loc->stmt)->loop_father;
  if (loop->num  == loc_loop->num
      || flow_loop_nested_p (loop, loc_loop))
    return 0;
  return (bb_loop_postorder[loop->num] < bb_loop_postorder[loc_loop->num]
	  ? -1 : 1);
}

/* Iterates over all locations of REF in LOOP and its subloops calling
   fn.operator() with the location as argument.  When that operator
   returns true the iteration is stopped and true is returned.
   Otherwise false is returned.  */

template <typename FN>
static bool
for_all_locs_in_loop (class loop *loop, im_mem_ref *ref, FN fn)
{
  unsigned i;
  mem_ref_loc *loc;

  /* Search for the cluster of locs in the accesses_in_loop vector
     which is sorted after postorder index of the loop father.  */
  loc = ref->accesses_in_loop.bsearch (loop, find_ref_loc_in_loop_cmp,
				       bb_loop_postorder);
  if (!loc)
    return false;

  /* We have found one location inside loop or its sub-loops.  Iterate
     both forward and backward to cover the whole cluster.  */
  i = loc - ref->accesses_in_loop.address ();
  while (i > 0)
    {
      --i;
      mem_ref_loc *l = &ref->accesses_in_loop[i];
      if (!flow_bb_inside_loop_p (loop, gimple_bb (l->stmt)))
	break;
      if (fn (l))
	return true;
    }
  for (i = loc - ref->accesses_in_loop.address ();
       i < ref->accesses_in_loop.length (); ++i)
    {
      mem_ref_loc *l = &ref->accesses_in_loop[i];
      if (!flow_bb_inside_loop_p (loop, gimple_bb (l->stmt)))
	break;
      if (fn (l))
	return true;
    }

  return false;
}

/* Rewrites location LOC by TMP_VAR.  */

class rewrite_mem_ref_loc
{
public:
  rewrite_mem_ref_loc (tree tmp_var_) : tmp_var (tmp_var_) {}
  bool operator () (mem_ref_loc *loc);
  tree tmp_var;
};

bool
rewrite_mem_ref_loc::operator () (mem_ref_loc *loc)
{
  *loc->ref = tmp_var;
  update_stmt (loc->stmt);
  return false;
}

/* Rewrites all references to REF in LOOP by variable TMP_VAR.  */

static void
rewrite_mem_refs (class loop *loop, im_mem_ref *ref, tree tmp_var)
{
  for_all_locs_in_loop (loop, ref, rewrite_mem_ref_loc (tmp_var));
}

/* Stores the first reference location in LOCP.  */

class first_mem_ref_loc_1
{
public:
  first_mem_ref_loc_1 (mem_ref_loc **locp_) : locp (locp_) {}
  bool operator () (mem_ref_loc *loc);
  mem_ref_loc **locp;
};

bool
first_mem_ref_loc_1::operator () (mem_ref_loc *loc)
{
  *locp = loc;
  return true;
}

/* Returns the first reference location to REF in LOOP.  */

static mem_ref_loc *
first_mem_ref_loc (class loop *loop, im_mem_ref *ref)
{
  mem_ref_loc *locp = NULL;
  for_all_locs_in_loop (loop, ref, first_mem_ref_loc_1 (&locp));
  return locp;
}

/* Helper function for execute_sm.  Emit code to store TMP_VAR into
   MEM along edge EX.

   The store is only done if MEM has changed.  We do this so no
   changes to MEM occur on code paths that did not originally store
   into it.

   The common case for execute_sm will transform:

     for (...) {
       if (foo)
         stuff;
       else
         MEM = TMP_VAR;
     }

   into:

     lsm = MEM;
     for (...) {
       if (foo)
         stuff;
       else
         lsm = TMP_VAR;
     }
     MEM = lsm;

  This function will generate:

     lsm = MEM;

     lsm_flag = false;
     ...
     for (...) {
       if (foo)
         stuff;
       else {
         lsm = TMP_VAR;
         lsm_flag = true;
       }
     }
     if (lsm_flag)	<--
       MEM = lsm;	<-- (X)

  In case MEM and TMP_VAR are NULL the function will return the then
  block so the caller can insert (X) and other related stmts. 
*/

static basic_block
execute_sm_if_changed (edge ex, tree mem, tree tmp_var, tree flag,
		       edge preheader, hash_set <basic_block> *flag_bbs,
		       edge &append_cond_position, edge &last_cond_fallthru)
{
  basic_block new_bb, then_bb, old_dest;
  bool loop_has_only_one_exit;
  edge then_old_edge;
  gimple_stmt_iterator gsi;
  gimple *stmt;
  bool irr = ex->flags & EDGE_IRREDUCIBLE_LOOP;

  profile_count count_sum = profile_count::zero ();
  int nbbs = 0, ncount = 0;
  profile_probability flag_probability = profile_probability::uninitialized ();

  /* Flag is set in FLAG_BBS. Determine probability that flag will be true
     at loop exit.

     This code may look fancy, but it cannot update profile very realistically
     because we do not know the probability that flag will be true at given
     loop exit.

     We look for two interesting extremes
       - when exit is dominated by block setting the flag, we know it will
         always be true.  This is a common case.
       - when all blocks setting the flag have very low frequency we know
         it will likely be false.
     In all other cases we default to 2/3 for flag being true.  */

  for (hash_set<basic_block>::iterator it = flag_bbs->begin ();
       it != flag_bbs->end (); ++it)
    {
       if ((*it)->count.initialized_p ())
         count_sum += (*it)->count, ncount ++;
       if (dominated_by_p (CDI_DOMINATORS, ex->src, *it))
	 flag_probability = profile_probability::always ();
       nbbs++;
    }

  profile_probability cap = profile_probability::always ().apply_scale (2, 3);

  if (flag_probability.initialized_p ())
    ;
  else if (ncount == nbbs
	   && preheader->count () >= count_sum && preheader->count ().nonzero_p ())
    {
      flag_probability = count_sum.probability_in (preheader->count ());
      if (flag_probability > cap)
	flag_probability = cap;
    }

  if (!flag_probability.initialized_p ())
    flag_probability = cap;

  /* ?? Insert store after previous store if applicable.  See note
     below.  */
  if (append_cond_position)
    ex = append_cond_position;

  loop_has_only_one_exit = single_pred_p (ex->dest);

  if (loop_has_only_one_exit)
    ex = split_block_after_labels (ex->dest);
  else
    {
      for (gphi_iterator gpi = gsi_start_phis (ex->dest);
	   !gsi_end_p (gpi); gsi_next (&gpi))
	{
	  gphi *phi = gpi.phi ();
	  if (virtual_operand_p (gimple_phi_result (phi)))
	    continue;

	  /* When the destination has a non-virtual PHI node with multiple
	     predecessors make sure we preserve the PHI structure by
	     forcing a forwarder block so that hoisting of that PHI will
	     still work.  */
	  split_edge (ex);
	  break;
	}
    }

  old_dest = ex->dest;
  new_bb = split_edge (ex);
  then_bb = create_empty_bb (new_bb);
  then_bb->count = new_bb->count.apply_probability (flag_probability);
  if (irr)
    then_bb->flags = BB_IRREDUCIBLE_LOOP;
  add_bb_to_loop (then_bb, new_bb->loop_father);

  gsi = gsi_start_bb (new_bb);
  stmt = gimple_build_cond (NE_EXPR, flag, boolean_false_node,
			    NULL_TREE, NULL_TREE);
  gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);

  /* Insert actual store.  */
  if (mem)
    {
      gsi = gsi_start_bb (then_bb);
      stmt = gimple_build_assign (unshare_expr (mem), tmp_var);
      gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
    }

  edge e1 = single_succ_edge (new_bb);
  edge e2 = make_edge (new_bb, then_bb,
	               EDGE_TRUE_VALUE | (irr ? EDGE_IRREDUCIBLE_LOOP : 0));
  e2->probability = flag_probability;

  e1->flags |= EDGE_FALSE_VALUE | (irr ? EDGE_IRREDUCIBLE_LOOP : 0);
  e1->flags &= ~EDGE_FALLTHRU;

  e1->probability = flag_probability.invert ();

  then_old_edge = make_single_succ_edge (then_bb, old_dest,
			     EDGE_FALLTHRU | (irr ? EDGE_IRREDUCIBLE_LOOP : 0));

  set_immediate_dominator (CDI_DOMINATORS, then_bb, new_bb);

  if (append_cond_position)
    {
      basic_block prevbb = last_cond_fallthru->src;
      redirect_edge_succ (last_cond_fallthru, new_bb);
      set_immediate_dominator (CDI_DOMINATORS, new_bb, prevbb);
      set_immediate_dominator (CDI_DOMINATORS, old_dest,
			       recompute_dominator (CDI_DOMINATORS, old_dest));
    }

  /* ?? Because stores may alias, they must happen in the exact
     sequence they originally happened.  Save the position right after
     the (_lsm) store we just created so we can continue appending after
     it and maintain the original order.  */
  append_cond_position = then_old_edge;
  last_cond_fallthru = find_edge (new_bb, old_dest);

  if (!loop_has_only_one_exit)
    for (gphi_iterator gpi = gsi_start_phis (old_dest);
	 !gsi_end_p (gpi); gsi_next (&gpi))
      {
	gphi *phi = gpi.phi ();
	unsigned i;

	for (i = 0; i < gimple_phi_num_args (phi); i++)
	  if (gimple_phi_arg_edge (phi, i)->src == new_bb)
	    {
	      tree arg = gimple_phi_arg_def (phi, i);
	      add_phi_arg (phi, arg, then_old_edge, UNKNOWN_LOCATION);
	      update_stmt (phi);
	    }
      }

  return then_bb;
}

/* When REF is set on the location, set flag indicating the store.  */

class sm_set_flag_if_changed
{
public:
  sm_set_flag_if_changed (tree flag_, hash_set <basic_block> *bbs_)
	 : flag (flag_), bbs (bbs_) {}
  bool operator () (mem_ref_loc *loc);
  tree flag;
  hash_set <basic_block> *bbs;
};

bool
sm_set_flag_if_changed::operator () (mem_ref_loc *loc)
{
  /* Only set the flag for writes.  */
  if (is_gimple_assign (loc->stmt)
      && gimple_assign_lhs_ptr (loc->stmt) == loc->ref)
    {
      gimple_stmt_iterator gsi = gsi_for_stmt (loc->stmt);
      gimple *stmt = gimple_build_assign (flag, boolean_true_node);
      gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
      bbs->add (gimple_bb (stmt));
    }
  return false;
}

/* Helper function for execute_sm.  On every location where REF is
   set, set an appropriate flag indicating the store.  */

static tree
execute_sm_if_changed_flag_set (class loop *loop, im_mem_ref *ref,
				hash_set <basic_block> *bbs)
{
  tree flag;
  char *str = get_lsm_tmp_name (ref->mem.ref, ~0, "_flag");
  flag = create_tmp_reg (boolean_type_node, str);
  for_all_locs_in_loop (loop, ref, sm_set_flag_if_changed (flag, bbs));
  return flag;
}

struct sm_aux
{
  tree tmp_var;
  tree store_flag;
  hash_set <basic_block> flag_bbs;
};

/* Executes store motion of memory reference REF from LOOP.
   Exits from the LOOP are stored in EXITS.  The initialization of the
   temporary variable is put to the preheader of the loop, and assignments
   to the reference from the temporary variable are emitted to exits.  */

static void
execute_sm (class loop *loop, im_mem_ref *ref,
	    hash_map<im_mem_ref *, sm_aux *> &aux_map, bool maybe_mt,
	    bool use_other_flag_var)
{
  gassign *load;
  struct fmt_data fmt_data;
  struct lim_aux_data *lim_data;
  bool multi_threaded_model_p = false;
  gimple_stmt_iterator gsi;
  sm_aux *aux = new sm_aux;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Executing store motion of ");
      print_generic_expr (dump_file, ref->mem.ref);
      fprintf (dump_file, " from loop %d\n", loop->num);
    }

  aux->tmp_var = create_tmp_reg (TREE_TYPE (ref->mem.ref),
				 get_lsm_tmp_name (ref->mem.ref, ~0));

  fmt_data.loop = loop;
  fmt_data.orig_loop = loop;
  for_each_index (&ref->mem.ref, force_move_till, &fmt_data);

  bool always_stored = ref_always_accessed_p (loop, ref, true);
  if (maybe_mt
      && (bb_in_transaction (loop_preheader_edge (loop)->src)
	  || (! flag_store_data_races && ! always_stored)))
    multi_threaded_model_p = true;

  if (multi_threaded_model_p && !use_other_flag_var)
    aux->store_flag
      = execute_sm_if_changed_flag_set (loop, ref, &aux->flag_bbs);
  else
    aux->store_flag = NULL_TREE;

  /* Remember variable setup.  */
  aux_map.put (ref, aux);

  rewrite_mem_refs (loop, ref, aux->tmp_var);

  /* Emit the load code on a random exit edge or into the latch if
     the loop does not exit, so that we are sure it will be processed
     by move_computations after all dependencies.  */
  gsi = gsi_for_stmt (first_mem_ref_loc (loop, ref)->stmt);

  /* Avoid doing a load if there was no load of the ref in the loop.
     Esp. when the ref is not always stored we cannot optimize it
     away later.  But when it is not always stored we must use a conditional
     store then.  */
  if ((!always_stored && !multi_threaded_model_p)
      || (ref->loaded && bitmap_bit_p (ref->loaded, loop->num)))
    load = gimple_build_assign (aux->tmp_var, unshare_expr (ref->mem.ref));
  else
    {
      /* If not emitting a load mark the uninitialized state on the
	 loop entry as not to be warned for.  */
      tree uninit = create_tmp_reg (TREE_TYPE (aux->tmp_var));
      suppress_warning (uninit, OPT_Wuninitialized);
      load = gimple_build_assign (aux->tmp_var, uninit);
    }
  lim_data = init_lim_data (load);
  lim_data->max_loop = loop;
  lim_data->tgt_loop = loop;
  gsi_insert_before (&gsi, load, GSI_SAME_STMT);

  if (aux->store_flag)
    {
      load = gimple_build_assign (aux->store_flag, boolean_false_node);
      lim_data = init_lim_data (load);
      lim_data->max_loop = loop;
      lim_data->tgt_loop = loop;
      gsi_insert_before (&gsi, load, GSI_SAME_STMT);
    }
}

/* sm_ord is used for ordinary stores we can retain order with respect
       to other stores
   sm_unord is used for conditional executed stores which need to be
       able to execute in arbitrary order with respect to other stores
   sm_other is used for stores we do not try to apply store motion to.  */
enum sm_kind { sm_ord, sm_unord, sm_other };
struct seq_entry
{
  seq_entry () {}
  seq_entry (unsigned f, sm_kind k, tree fr = NULL)
    : first (f), second (k), from (fr) {}
  unsigned first;
  sm_kind second;
  tree from;
};

static void
execute_sm_exit (class loop *loop, edge ex, vec<seq_entry> &seq,
		 hash_map<im_mem_ref *, sm_aux *> &aux_map, sm_kind kind,
		 edge &append_cond_position, edge &last_cond_fallthru)
{
  /* Sink the stores to exit from the loop.  */
  for (unsigned i = seq.length (); i > 0; --i)
    {
      im_mem_ref *ref = memory_accesses.refs_list[seq[i-1].first];
      if (seq[i-1].second == sm_other)
	{
	  gcc_assert (kind == sm_ord && seq[i-1].from != NULL_TREE);
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Re-issueing dependent store of ");
	      print_generic_expr (dump_file, ref->mem.ref);
	      fprintf (dump_file, " from loop %d on exit %d -> %d\n",
		       loop->num, ex->src->index, ex->dest->index);
	    }
	  gassign *store = gimple_build_assign (unshare_expr (ref->mem.ref),
						seq[i-1].from);
	  gsi_insert_on_edge (ex, store);
	}
      else
	{
	  sm_aux *aux = *aux_map.get (ref);
	  if (!aux->store_flag || kind == sm_ord)
	    {
	      gassign *store;
	      store = gimple_build_assign (unshare_expr (ref->mem.ref),
					   aux->tmp_var);
	      gsi_insert_on_edge (ex, store);
	    }
	  else
	    execute_sm_if_changed (ex, ref->mem.ref, aux->tmp_var,
				   aux->store_flag,
				   loop_preheader_edge (loop), &aux->flag_bbs,
				   append_cond_position, last_cond_fallthru);
	}
    }
}

/* Push the SM candidate at index PTR in the sequence SEQ down until
   we hit the next SM candidate.  Return true if that went OK and
   false if we could not disambiguate agains another unrelated ref.
   Update *AT to the index where the candidate now resides.  */

static bool
sm_seq_push_down (vec<seq_entry> &seq, unsigned ptr, unsigned *at)
{
  *at = ptr;
  for (; ptr > 0; --ptr)
    {
      seq_entry &new_cand = seq[ptr];
      seq_entry &against = seq[ptr-1];
      if (against.second == sm_ord
	  || (against.second == sm_other && against.from != NULL_TREE))
	/* Found the tail of the sequence.  */
	break;
      /* We may not ignore self-dependences here.  */
      if (new_cand.first == against.first
	  || !refs_independent_p (memory_accesses.refs_list[new_cand.first],
				  memory_accesses.refs_list[against.first],
				  false))
	/* ???  Prune new_cand from the list of refs to apply SM to.  */
	return false;
      std::swap (new_cand, against);
      *at = ptr - 1;
    }
  return true;
}

/* Computes the sequence of stores from candidates in REFS_NOT_IN_SEQ to SEQ
   walking backwards from VDEF (or the end of BB if VDEF is NULL).  */

static int
sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
		 vec<seq_entry> &seq, bitmap refs_not_in_seq,
		 bitmap refs_not_supported, bool forked,
		 bitmap fully_visited)
{
  if (!vdef)
    for (gimple_stmt_iterator gsi = gsi_last_bb (bb); !gsi_end_p (gsi);
	 gsi_prev (&gsi))
      {
	vdef = gimple_vdef (gsi_stmt (gsi));
	if (vdef)
	  break;
      }
  if (!vdef)
    {
      gphi *vphi = get_virtual_phi (bb);
      if (vphi)
	vdef = gimple_phi_result (vphi);
    }
  if (!vdef)
    {
      if (single_pred_p (bb))
	/* This handles the perfect nest case.  */
	return sm_seq_valid_bb (loop, single_pred (bb), vdef,
				seq, refs_not_in_seq, refs_not_supported,
				forked, fully_visited);
      return 0;
    }
  do
    {
      gimple *def = SSA_NAME_DEF_STMT (vdef);
      if (gimple_bb (def) != bb)
	{
	  /* If we forked by processing a PHI do not allow our walk to
	     merge again until we handle that robustly.  */
	  if (forked)
	    {
	      /* Mark refs_not_in_seq as unsupported.  */
	      bitmap_ior_into (refs_not_supported, refs_not_in_seq);
	      return 1;
	    }
	  /* Otherwise it doesn't really matter if we end up in different
	     BBs.  */
	  bb = gimple_bb (def);
	}
      if (gphi *phi = dyn_cast <gphi *> (def))
	{
	  /* Handle CFG merges.  Until we handle forks (gimple_bb (def) != bb)
	     this is still linear.
	     Eventually we want to cache intermediate results per BB
	     (but we can't easily cache for different exits?).  */
	  /* Stop at PHIs with possible backedges.  */
	  if (bb == bb->loop_father->header
	      || bb->flags & BB_IRREDUCIBLE_LOOP)
	    {
	      /* Mark refs_not_in_seq as unsupported.  */
	      bitmap_ior_into (refs_not_supported, refs_not_in_seq);
	      return 1;
	    }
	  if (gimple_phi_num_args (phi) == 1)
	    return sm_seq_valid_bb (loop, gimple_phi_arg_edge (phi, 0)->src,
				    gimple_phi_arg_def (phi, 0), seq,
				    refs_not_in_seq, refs_not_supported,
				    false, fully_visited);
	  if (bitmap_bit_p (fully_visited,
			    SSA_NAME_VERSION (gimple_phi_result (phi))))
	    return 1;
	  auto_vec<seq_entry> first_edge_seq;
	  auto_bitmap tem_refs_not_in_seq (&lim_bitmap_obstack);
	  int eret;
	  bitmap_copy (tem_refs_not_in_seq, refs_not_in_seq);
	  eret = sm_seq_valid_bb (loop, gimple_phi_arg_edge (phi, 0)->src,
				  gimple_phi_arg_def (phi, 0),
				  first_edge_seq,
				  tem_refs_not_in_seq, refs_not_supported,
				  true, fully_visited);
	  if (eret != 1)
	    return -1;
	  /* Simplify our lives by pruning the sequence of !sm_ord.  */
	  while (!first_edge_seq.is_empty ()
		 && first_edge_seq.last ().second != sm_ord)
	    first_edge_seq.pop ();
	  for (unsigned int i = 1; i < gimple_phi_num_args (phi); ++i)
	    {
	      tree vuse = gimple_phi_arg_def (phi, i);
	      edge e = gimple_phi_arg_edge (phi, i);
	      auto_vec<seq_entry> edge_seq;
	      bitmap_and_compl (tem_refs_not_in_seq,
				refs_not_in_seq, refs_not_supported);
	      /* If we've marked all refs we search for as unsupported
		 we can stop processing and use the sequence as before
		 the PHI.  */
	      if (bitmap_empty_p (tem_refs_not_in_seq))
		return 1;
	      eret = sm_seq_valid_bb (loop, e->src, vuse, edge_seq,
				      tem_refs_not_in_seq, refs_not_supported,
				      true, fully_visited);
	      if (eret != 1)
		return -1;
	      /* Simplify our lives by pruning the sequence of !sm_ord.  */
	      while (!edge_seq.is_empty ()
		     && edge_seq.last ().second != sm_ord)
		edge_seq.pop ();
	      unsigned min_len = MIN(first_edge_seq.length (),
				     edge_seq.length ());
	      /* Incrementally merge seqs into first_edge_seq.  */
	      int first_uneq = -1;
	      auto_vec<seq_entry, 2> extra_refs;
	      for (unsigned int i = 0; i < min_len; ++i)
		{
		  /* ???  We can more intelligently merge when we face different
		     order by additional sinking operations in one sequence.
		     For now we simply mark them as to be processed by the
		     not order-preserving SM code.  */
		  if (first_edge_seq[i].first != edge_seq[i].first)
		    {
		      if (first_edge_seq[i].second == sm_ord)
			bitmap_set_bit (refs_not_supported,
					first_edge_seq[i].first);
		      if (edge_seq[i].second == sm_ord)
			bitmap_set_bit (refs_not_supported, edge_seq[i].first);
		      first_edge_seq[i].second = sm_other;
		      first_edge_seq[i].from = NULL_TREE;
		      /* Record the dropped refs for later processing.  */
		      if (first_uneq == -1)
			first_uneq = i;
		      extra_refs.safe_push (seq_entry (edge_seq[i].first,
						       sm_other, NULL_TREE));
		    }
		  /* sm_other prevails.  */
		  else if (first_edge_seq[i].second != edge_seq[i].second)
		    {
		      /* Make sure the ref is marked as not supported.  */
		      bitmap_set_bit (refs_not_supported,
				      first_edge_seq[i].first);
		      first_edge_seq[i].second = sm_other;
		      first_edge_seq[i].from = NULL_TREE;
		    }
		  else if (first_edge_seq[i].second == sm_other
			   && first_edge_seq[i].from != NULL_TREE
			   && (edge_seq[i].from == NULL_TREE
			       || !operand_equal_p (first_edge_seq[i].from,
						    edge_seq[i].from, 0)))
		    first_edge_seq[i].from = NULL_TREE;
		}
	      /* Any excess elements become sm_other since they are now
		 coonditionally executed.  */
	      if (first_edge_seq.length () > edge_seq.length ())
		{
		  for (unsigned i = edge_seq.length ();
		       i < first_edge_seq.length (); ++i)
		    {
		      if (first_edge_seq[i].second == sm_ord)
			bitmap_set_bit (refs_not_supported,
					first_edge_seq[i].first);
		      first_edge_seq[i].second = sm_other;
		    }
		}
	      else if (edge_seq.length () > first_edge_seq.length ())
		{
		  if (first_uneq == -1)
		    first_uneq = first_edge_seq.length ();
		  for (unsigned i = first_edge_seq.length ();
		       i < edge_seq.length (); ++i)
		    {
		      if (edge_seq[i].second == sm_ord)
			bitmap_set_bit (refs_not_supported, edge_seq[i].first);
		      extra_refs.safe_push (seq_entry (edge_seq[i].first,
						       sm_other, NULL_TREE));
		    }
		}
	      /* Put unmerged refs at first_uneq to force dependence checking
		 on them.  */
	      if (first_uneq != -1)
		{
		  /* Missing ordered_splice_at.  */
		  if ((unsigned)first_uneq == first_edge_seq.length ())
		    first_edge_seq.safe_splice (extra_refs);
		  else
		    {
		      unsigned fes_length = first_edge_seq.length ();
		      first_edge_seq.safe_grow (fes_length
						+ extra_refs.length ());
		      memmove (&first_edge_seq[first_uneq + extra_refs.length ()],
			       &first_edge_seq[first_uneq],
			       (fes_length - first_uneq) * sizeof (seq_entry));
		      memcpy (&first_edge_seq[first_uneq],
			      extra_refs.address (),
			      extra_refs.length () * sizeof (seq_entry));
		    }
		}
	    }
	  /* Use the sequence from the first edge and push SMs down.  */
	  for (unsigned i = 0; i < first_edge_seq.length (); ++i)
	    {
	      unsigned id = first_edge_seq[i].first;
	      seq.safe_push (first_edge_seq[i]);
	      unsigned new_idx;
	      if ((first_edge_seq[i].second == sm_ord
		   || (first_edge_seq[i].second == sm_other
		       && first_edge_seq[i].from != NULL_TREE))
		  && !sm_seq_push_down (seq, seq.length () - 1, &new_idx))
		{
		  if (first_edge_seq[i].second == sm_ord)
		    bitmap_set_bit (refs_not_supported, id);
		  /* Mark it sm_other.  */
		  seq[new_idx].second = sm_other;
		  seq[new_idx].from = NULL_TREE;
		}
	    }
	  bitmap_set_bit (fully_visited,
			  SSA_NAME_VERSION (gimple_phi_result (phi)));
	  return 1;
	}
      lim_aux_data *data = get_lim_data (def);
      gcc_assert (data);
      if (data->ref == UNANALYZABLE_MEM_ID)
	return -1;
      /* Stop at memory references which we can't move.  */
      else if (memory_accesses.refs_list[data->ref]->mem.ref == error_mark_node)
	{
	  /* Mark refs_not_in_seq as unsupported.  */
	  bitmap_ior_into (refs_not_supported, refs_not_in_seq);
	  return 1;
	}
      /* One of the stores we want to apply SM to and we've not yet seen.  */
      else if (bitmap_clear_bit (refs_not_in_seq, data->ref))
	{
	  seq.safe_push (seq_entry (data->ref, sm_ord));

	  /* 1) push it down the queue until a SMed
	     and not ignored ref is reached, skipping all not SMed refs
	     and ignored refs via non-TBAA disambiguation.  */
	  unsigned new_idx;
	  if (!sm_seq_push_down (seq, seq.length () - 1, &new_idx)
	      /* If that fails but we did not fork yet continue, we'll see
		 to re-materialize all of the stores in the sequence then.
		 Further stores will only be pushed up to this one.  */
	      && forked)
	    {
	      bitmap_set_bit (refs_not_supported, data->ref);
	      /* Mark it sm_other.  */
	      seq[new_idx].second = sm_other;
	    }

	  /* 2) check whether we've seen all refs we want to SM and if so
	     declare success for the active exit  */
	  if (bitmap_empty_p (refs_not_in_seq))
	    return 1;
	}
      else
	/* Another store not part of the final sequence.  Simply push it.  */
	seq.safe_push (seq_entry (data->ref, sm_other,
				  gimple_assign_rhs1 (def)));

      vdef = gimple_vuse (def);
    }
  while (1);
}

/* Hoists memory references MEM_REFS out of LOOP.  EXITS is the list of exit
   edges of the LOOP.  */

static void
hoist_memory_references (class loop *loop, bitmap mem_refs,
			 const vec<edge> &exits)
{
  im_mem_ref *ref;
  unsigned  i;
  bitmap_iterator bi;

  /* There's a special case we can use ordered re-materialization for
     conditionally excuted stores which is when all stores in the loop
     happen in the same basic-block.  In that case we know we'll reach
     all stores and thus can simply process that BB and emit a single
     conditional block of ordered materializations.  See PR102436.  */
  basic_block single_store_bb = NULL;
  EXECUTE_IF_SET_IN_BITMAP (&memory_accesses.all_refs_stored_in_loop[loop->num],
			    0, i, bi)
    {
      bool fail = false;
      ref = memory_accesses.refs_list[i];
      for (auto loc : ref->accesses_in_loop)
	if (!gimple_vdef (loc.stmt))
	  ;
	else if (!single_store_bb)
	  {
	    single_store_bb = gimple_bb (loc.stmt);
	    bool conditional = false;
	    for (edge e : exits)
	      if (!dominated_by_p (CDI_DOMINATORS, e->src, single_store_bb))
		{
		  /* Conditional as seen from e.  */
		  conditional = true;
		  break;
		}
	    if (!conditional)
	      {
		fail = true;
		break;
	      }
	  }
	else if (single_store_bb != gimple_bb (loc.stmt))
	  {
	    fail = true;
	    break;
	  }
      if (fail)
	{
	  single_store_bb = NULL;
	  break;
	}
    }
  if (single_store_bb)
    {
      /* Analyze the single block with stores.  */
      auto_bitmap fully_visited;
      auto_bitmap refs_not_supported;
      auto_bitmap refs_not_in_seq;
      auto_vec<seq_entry> seq;
      bitmap_copy (refs_not_in_seq, mem_refs);
      int res = sm_seq_valid_bb (loop, single_store_bb, NULL_TREE,
				 seq, refs_not_in_seq, refs_not_supported,
				 false, fully_visited);
      if (res != 1)
	{
	  /* Unhandled refs can still fail this.  */
	  bitmap_clear (mem_refs);
	  return;
	}

      /* We cannot handle sm_other since we neither remember the
	 stored location nor the value at the point we execute them.  */
      for (unsigned i = 0; i < seq.length (); ++i)
	{
	  unsigned new_i;
	  if (seq[i].second == sm_other
	      && seq[i].from != NULL_TREE)
	    seq[i].from = NULL_TREE;
	  else if ((seq[i].second == sm_ord
		    || (seq[i].second == sm_other
			&& seq[i].from != NULL_TREE))
		   && !sm_seq_push_down (seq, i, &new_i))
	    {
	      bitmap_set_bit (refs_not_supported, seq[new_i].first);
	      seq[new_i].second = sm_other;
	      seq[new_i].from = NULL_TREE;
	    }
	}
      bitmap_and_compl_into (mem_refs, refs_not_supported);
      if (bitmap_empty_p (mem_refs))
	return;

      /* Prune seq.  */
      while (seq.last ().second == sm_other
	     && seq.last ().from == NULL_TREE)
	seq.pop ();

      hash_map<im_mem_ref *, sm_aux *> aux_map;

      /* Execute SM but delay the store materialization for ordered
	 sequences on exit.  */
      bool first_p = true;
      EXECUTE_IF_SET_IN_BITMAP (mem_refs, 0, i, bi)
	{
	  ref = memory_accesses.refs_list[i];
	  execute_sm (loop, ref, aux_map, true, !first_p);
	  first_p = false;
	}

      /* Get at the single flag variable we eventually produced.  */
      im_mem_ref *ref
	= memory_accesses.refs_list[bitmap_first_set_bit (mem_refs)];
      sm_aux *aux = *aux_map.get (ref);

      /* Materialize ordered store sequences on exits.  */
      edge e;
      FOR_EACH_VEC_ELT (exits, i, e)
	{
	  edge append_cond_position = NULL;
	  edge last_cond_fallthru = NULL;
	  edge insert_e = e;
	  /* Construct the single flag variable control flow and insert
	     the ordered seq of stores in the then block.  With
	     -fstore-data-races we can do the stores unconditionally.  */
	  if (aux->store_flag)
	    insert_e
	      = single_pred_edge
		  (execute_sm_if_changed (e, NULL_TREE, NULL_TREE,
					  aux->store_flag,
					  loop_preheader_edge (loop),
					  &aux->flag_bbs, append_cond_position,
					  last_cond_fallthru));
	  execute_sm_exit (loop, insert_e, seq, aux_map, sm_ord,
			   append_cond_position, last_cond_fallthru);
	  gsi_commit_one_edge_insert (insert_e, NULL);
	}

      for (hash_map<im_mem_ref *, sm_aux *>::iterator iter = aux_map.begin ();
	   iter != aux_map.end (); ++iter)
	delete (*iter).second;

      return;
    }

  /* To address PR57359 before actually applying store-motion check
     the candidates found for validity with regards to reordering
     relative to other stores which we until here disambiguated using
     TBAA which isn't valid.
     What matters is the order of the last stores to the mem_refs
     with respect to the other stores of the loop at the point of the
     loop exits.  */

  /* For each exit compute the store order, pruning from mem_refs
     on the fly.  */
  /* The complexity of this is at least
     O(number of exits * number of SM refs) but more approaching
     O(number of exits * number of SM refs * number of stores).  */
  /* ???  Somehow do this in a single sweep over the loop body.  */
  auto_vec<std::pair<edge, vec<seq_entry> > > sms;
  auto_bitmap refs_not_supported (&lim_bitmap_obstack);
  edge e;
  FOR_EACH_VEC_ELT (exits, i, e)
    {
      vec<seq_entry> seq;
      seq.create (4);
      auto_bitmap refs_not_in_seq (&lim_bitmap_obstack);
      bitmap_and_compl (refs_not_in_seq, mem_refs, refs_not_supported);
      if (bitmap_empty_p (refs_not_in_seq))
	{
	  seq.release ();
	  break;
	}
      auto_bitmap fully_visited;
      int res = sm_seq_valid_bb (loop, e->src, NULL_TREE,
				 seq, refs_not_in_seq,
				 refs_not_supported, false,
				 fully_visited);
      if (res != 1)
	{
	  bitmap_copy (refs_not_supported, mem_refs);
	  seq.release ();
	  break;
	}
      sms.safe_push (std::make_pair (e, seq));
    }

  /* Prune pruned mem_refs from earlier processed exits.  */
  bool changed = !bitmap_empty_p (refs_not_supported);
  while (changed)
    {
      changed = false;
      std::pair<edge, vec<seq_entry> > *seq;
      FOR_EACH_VEC_ELT (sms, i, seq)
	{
	  bool need_to_push = false;
	  for (unsigned i = 0; i < seq->second.length (); ++i)
	    {
	      sm_kind kind = seq->second[i].second;
	      if (kind == sm_other && seq->second[i].from == NULL_TREE)
		break;
	      unsigned id = seq->second[i].first;
	      unsigned new_idx;
	      if (kind == sm_ord
		  && bitmap_bit_p (refs_not_supported, id))
		{
		  seq->second[i].second = sm_other;
		  gcc_assert (seq->second[i].from == NULL_TREE);
		  need_to_push = true;
		}
	      else if (need_to_push
		       && !sm_seq_push_down (seq->second, i, &new_idx))
		{
		  /* We need to push down both sm_ord and sm_other
		     but for the latter we need to disqualify all
		     following refs.  */
		  if (kind == sm_ord)
		    {
		      if (bitmap_set_bit (refs_not_supported, id))
			changed = true;
		      seq->second[new_idx].second = sm_other;
		    }
		  else
		    {
		      for (unsigned j = seq->second.length () - 1;
			   j > new_idx; --j)
			if (seq->second[j].second == sm_ord
			    && bitmap_set_bit (refs_not_supported,
					       seq->second[j].first))
			  changed = true;
		      seq->second.truncate (new_idx);
		      break;
		    }
		}
	    }
	}
    }
  std::pair<edge, vec<seq_entry> > *seq;
  FOR_EACH_VEC_ELT (sms, i, seq)
    {
      /* Prune sm_other from the end.  */
      while (!seq->second.is_empty ()
	     && seq->second.last ().second == sm_other)
	seq->second.pop ();
      /* Prune duplicates from the start.  */
      auto_bitmap seen (&lim_bitmap_obstack);
      unsigned j, k;
      for (j = k = 0; j < seq->second.length (); ++j)
	if (bitmap_set_bit (seen, seq->second[j].first))
	  {
	    if (k != j)
	      seq->second[k] = seq->second[j];
	    ++k;
	  }
      seq->second.truncate (k);
      /* And verify.  */
      seq_entry *e;
      FOR_EACH_VEC_ELT (seq->second, j, e)
	gcc_assert (e->second == sm_ord
		    || (e->second == sm_other && e->from != NULL_TREE));
    }

  /* Verify dependence for refs we cannot handle with the order preserving
     code (refs_not_supported) or prune them from mem_refs.  */
  auto_vec<seq_entry> unord_refs;
  EXECUTE_IF_SET_IN_BITMAP (refs_not_supported, 0, i, bi)
    {
      ref = memory_accesses.refs_list[i];
      if (!ref_indep_loop_p (loop, ref, sm_waw))
	bitmap_clear_bit (mem_refs, i);
      /* We've now verified store order for ref with respect to all other
	 stores in the loop does not matter.  */
      else
	unord_refs.safe_push (seq_entry (i, sm_unord));
    }

  hash_map<im_mem_ref *, sm_aux *> aux_map;

  /* Execute SM but delay the store materialization for ordered
     sequences on exit.  */
  EXECUTE_IF_SET_IN_BITMAP (mem_refs, 0, i, bi)
    {
      ref = memory_accesses.refs_list[i];
      execute_sm (loop, ref, aux_map, bitmap_bit_p (refs_not_supported, i),
		  false);
    }

  /* Materialize ordered store sequences on exits.  */
  FOR_EACH_VEC_ELT (exits, i, e)
    {
      edge append_cond_position = NULL;
      edge last_cond_fallthru = NULL;
      if (i < sms.length ())
	{
	  gcc_assert (sms[i].first == e);
	  execute_sm_exit (loop, e, sms[i].second, aux_map, sm_ord,
			   append_cond_position, last_cond_fallthru);
	  sms[i].second.release ();
	}
      if (!unord_refs.is_empty ())
	execute_sm_exit (loop, e, unord_refs, aux_map, sm_unord,
			 append_cond_position, last_cond_fallthru);
      /* Commit edge inserts here to preserve the order of stores
	 when an exit exits multiple loops.  */
      gsi_commit_one_edge_insert (e, NULL);
    }

  for (hash_map<im_mem_ref *, sm_aux *>::iterator iter = aux_map.begin ();
       iter != aux_map.end (); ++iter)
    delete (*iter).second;
}

class ref_always_accessed
{
public:
  ref_always_accessed (class loop *loop_, bool stored_p_)
      : loop (loop_), stored_p (stored_p_) {}
  bool operator () (mem_ref_loc *loc);
  class loop *loop;
  bool stored_p;
};

bool
ref_always_accessed::operator () (mem_ref_loc *loc)
{
  class loop *must_exec;

  struct lim_aux_data *lim_data = get_lim_data (loc->stmt);
  if (!lim_data)
    return false;

  /* If we require an always executed store make sure the statement
     is a store.  */
  if (stored_p)
    {
      tree lhs = gimple_get_lhs (loc->stmt);
      if (!lhs
	  || !(DECL_P (lhs) || REFERENCE_CLASS_P (lhs)))
	return false;
    }

  must_exec = lim_data->always_executed_in;
  if (!must_exec)
    return false;

  if (must_exec == loop
      || flow_loop_nested_p (must_exec, loop))
    return true;

  return false;
}

/* Returns true if REF is always accessed in LOOP.  If STORED_P is true
   make sure REF is always stored to in LOOP.  */

static bool
ref_always_accessed_p (class loop *loop, im_mem_ref *ref, bool stored_p)
{
  return for_all_locs_in_loop (loop, ref,
			       ref_always_accessed (loop, stored_p));
}

/* Returns true if REF1 and REF2 are independent.  */

static bool
refs_independent_p (im_mem_ref *ref1, im_mem_ref *ref2, bool tbaa_p)
{
  if (ref1 == ref2)
    return true;

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Querying dependency of refs %u and %u: ",
	     ref1->id, ref2->id);

  if (mem_refs_may_alias_p (ref1, ref2, &memory_accesses.ttae_cache, tbaa_p))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "dependent.\n");
      return false;
    }
  else
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "independent.\n");
      return true;
    }
}

/* Returns true if REF is independent on all other accessess in LOOP.
   KIND specifies the kind of dependence to consider.
     lim_raw assumes REF is not stored in LOOP and disambiguates RAW
	     dependences so if true REF can be hoisted out of LOOP
     sm_war disambiguates a store REF against all other loads to see
	    whether the store can be sunk across loads out of LOOP
     sm_waw disambiguates a store REF against all other stores to see
	    whether the store can be sunk across stores out of LOOP.  */

static bool
ref_indep_loop_p (class loop *loop, im_mem_ref *ref, dep_kind kind)
{
  bool indep_p = true;
  bitmap refs_to_check;

  if (kind == sm_war)
    refs_to_check = &memory_accesses.refs_loaded_in_loop[loop->num];
  else
    refs_to_check = &memory_accesses.refs_stored_in_loop[loop->num];

  if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID)
      || ref->mem.ref == error_mark_node)
    indep_p = false;
  else
    {
      /* tri-state, { unknown, independent, dependent }  */
      dep_state state = query_loop_dependence (loop, ref, kind);
      if (state != dep_unknown)
	return state == dep_independent ? true : false;

      class loop *inner = loop->inner;
      while (inner)
	{
	  if (!ref_indep_loop_p (inner, ref, kind))
	    {
	      indep_p = false;
	      break;
	    }
	  inner = inner->next;
	}

      if (indep_p)
	{
	  unsigned i;
	  bitmap_iterator bi;
	  EXECUTE_IF_SET_IN_BITMAP (refs_to_check, 0, i, bi)
	    {
	      im_mem_ref *aref = memory_accesses.refs_list[i];
	      if (aref->mem.ref == error_mark_node)
		{
		  gimple *stmt = aref->accesses_in_loop[0].stmt;
		  if ((kind == sm_war
		       && ref_maybe_used_by_stmt_p (stmt, &ref->mem,
						    kind != sm_waw))
		      || stmt_may_clobber_ref_p_1 (stmt, &ref->mem,
						   kind != sm_waw))
		    {
		      indep_p = false;
		      break;
		    }
		}
	      else if (!refs_independent_p (ref, aref, kind != sm_waw))
		{
		  indep_p = false;
		  break;
		}
	    }
	}
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Querying %s dependencies of ref %u in loop %d: %s\n",
	     kind == lim_raw ? "RAW" : (kind == sm_war ? "SM WAR" : "SM WAW"),
	     ref->id, loop->num, indep_p ? "independent" : "dependent");

  /* Record the computed result in the cache.  */
  record_loop_dependence (loop, ref, kind,
			  indep_p ? dep_independent : dep_dependent);

  return indep_p;
}

class ref_in_loop_hot_body
{
public:
  ref_in_loop_hot_body (class loop *loop_) : l (loop_) {}
  bool operator () (mem_ref_loc *loc);
  class loop *l;
};

/* Check the coldest loop between loop L and innermost loop.  If there is one
   cold loop between L and INNER_LOOP, store motion can be performed, otherwise
   no cold loop means no store motion.  get_coldest_out_loop also handles cases
   when l is inner_loop.  */
bool
ref_in_loop_hot_body::operator () (mem_ref_loc *loc)
{
  basic_block curr_bb = gimple_bb (loc->stmt);
  class loop *inner_loop = curr_bb->loop_father;
  return get_coldest_out_loop (l, inner_loop, curr_bb);
}


/* Returns true if we can perform store motion of REF from LOOP.  */

static bool
can_sm_ref_p (class loop *loop, im_mem_ref *ref)
{
  tree base;

  /* Can't hoist unanalyzable refs.  */
  if (!MEM_ANALYZABLE (ref))
    return false;

  /* Can't hoist/sink aggregate copies.  */
  if (ref->mem.ref == error_mark_node)
    return false;

  /* It should be movable.  */
  if (!is_gimple_reg_type (TREE_TYPE (ref->mem.ref))
      || TREE_THIS_VOLATILE (ref->mem.ref)
      || !for_each_index (&ref->mem.ref, may_move_till, loop))
    return false;

  /* If it can throw fail, we do not properly update EH info.  */
  if (tree_could_throw_p (ref->mem.ref))
    return false;

  /* If it can trap, it must be always executed in LOOP.
     Readonly memory locations may trap when storing to them, but
     tree_could_trap_p is a predicate for rvalues, so check that
     explicitly.  */
  base = get_base_address (ref->mem.ref);
  if ((tree_could_trap_p (ref->mem.ref)
       || (DECL_P (base) && TREE_READONLY (base)))
      /* ???  We can at least use false here, allowing loads?  We
	 are forcing conditional stores if the ref is not always
	 stored to later anyway.  So this would only guard
	 the load we need to emit.  Thus when the ref is not
	 loaded we can elide this completely?  */
      && !ref_always_accessed_p (loop, ref, true))
    return false;

  /* Verify all loads of ref can be hoisted.  */
  if (ref->loaded
      && bitmap_bit_p (ref->loaded, loop->num)
      && !ref_indep_loop_p (loop, ref, lim_raw))
    return false;

  /* Verify the candidate can be disambiguated against all loads,
     that is, we can elide all in-loop stores.  Disambiguation
     against stores is done later when we cannot guarantee preserving
     the order of stores.  */
  if (!ref_indep_loop_p (loop, ref, sm_war))
    return false;

  /* Verify whether the candidate is hot for LOOP.  Only do store motion if the
    candidate's profile count is hot.  Statement in cold BB shouldn't be moved
    out of it's loop_father.  */
  if (!for_all_locs_in_loop (loop, ref, ref_in_loop_hot_body (loop)))
    return false;

  return true;
}

/* Marks the references in LOOP for that store motion should be performed
   in REFS_TO_SM.  SM_EXECUTED is the set of references for that store
   motion was performed in one of the outer loops.  */

static void
find_refs_for_sm (class loop *loop, bitmap sm_executed, bitmap refs_to_sm)
{
  bitmap refs = &memory_accesses.all_refs_stored_in_loop[loop->num];
  unsigned i;
  bitmap_iterator bi;
  im_mem_ref *ref;

  EXECUTE_IF_AND_COMPL_IN_BITMAP (refs, sm_executed, 0, i, bi)
    {
      ref = memory_accesses.refs_list[i];
      if (can_sm_ref_p (loop, ref) && dbg_cnt (lim))
	bitmap_set_bit (refs_to_sm, i);
    }
}

/* Checks whether LOOP (with exits stored in EXITS array) is suitable
   for a store motion optimization (i.e. whether we can insert statement
   on its exits).  */

static bool
loop_suitable_for_sm (class loop *loop ATTRIBUTE_UNUSED,
		      const vec<edge> &exits)
{
  unsigned i;
  edge ex;

  FOR_EACH_VEC_ELT (exits, i, ex)
    if (ex->flags & (EDGE_ABNORMAL | EDGE_EH))
      return false;

  return true;
}

/* Try to perform store motion for all memory references modified inside
   LOOP.  SM_EXECUTED is the bitmap of the memory references for that
   store motion was executed in one of the outer loops.  */

static void
store_motion_loop (class loop *loop, bitmap sm_executed)
{
  auto_vec<edge> exits = get_loop_exit_edges (loop);
  class loop *subloop;
  bitmap sm_in_loop = BITMAP_ALLOC (&lim_bitmap_obstack);

  if (loop_suitable_for_sm (loop, exits))
    {
      find_refs_for_sm (loop, sm_executed, sm_in_loop);
      if (!bitmap_empty_p (sm_in_loop))
	hoist_memory_references (loop, sm_in_loop, exits);
    }

  bitmap_ior_into (sm_executed, sm_in_loop);
  for (subloop = loop->inner; subloop != NULL; subloop = subloop->next)
    store_motion_loop (subloop, sm_executed);
  bitmap_and_compl_into (sm_executed, sm_in_loop);
  BITMAP_FREE (sm_in_loop);
}

/* Try to perform store motion for all memory references modified inside
   loops.  */

static void
do_store_motion (void)
{
  class loop *loop;
  bitmap sm_executed = BITMAP_ALLOC (&lim_bitmap_obstack);

  for (loop = current_loops->tree_root->inner; loop != NULL; loop = loop->next)
    store_motion_loop (loop, sm_executed);

  BITMAP_FREE (sm_executed);
}

/* Fills ALWAYS_EXECUTED_IN information for basic blocks of LOOP, i.e.
   for each such basic block bb records the outermost loop for that execution
   of its header implies execution of bb.  CONTAINS_CALL is the bitmap of
   blocks that contain a nonpure call.  */

static void
fill_always_executed_in_1 (class loop *loop, sbitmap contains_call)
{
  basic_block bb = NULL, last = NULL;
  edge e;
  class loop *inn_loop = loop;

  if (ALWAYS_EXECUTED_IN (loop->header) == NULL)
    {
      auto_vec<basic_block, 64> worklist;
      worklist.reserve_exact (loop->num_nodes);
      worklist.quick_push (loop->header);
      do
	{
	  edge_iterator ei;
	  bb = worklist.pop ();

	  if (!flow_bb_inside_loop_p (inn_loop, bb))
	    {
	      /* When we are leaving a possibly infinite inner loop
		 we have to stop processing.  */
	      if (!finite_loop_p (inn_loop))
		break;
	      /* If the loop was finite we can continue with processing
		 the loop we exited to.  */
	      inn_loop = bb->loop_father;
	    }

	  if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
	    last = bb;

	  if (bitmap_bit_p (contains_call, bb->index))
	    break;

	  /* If LOOP exits from this BB stop processing.  */
	  FOR_EACH_EDGE (e, ei, bb->succs)
	    if (!flow_bb_inside_loop_p (loop, e->dest))
	      break;
	  if (e)
	    break;

	  /* A loop might be infinite (TODO use simple loop analysis
	     to disprove this if possible).  */
	  if (bb->flags & BB_IRREDUCIBLE_LOOP)
	    break;

	  if (bb->loop_father->header == bb)
	    /* Record that we enter into a subloop since it might not
	       be finite.  */
	    /* ???  Entering into a not always executed subloop makes
	       fill_always_executed_in quadratic in loop depth since
	       we walk those loops N times.  This is not a problem
	       in practice though, see PR102253 for a worst-case testcase.  */
	    inn_loop = bb->loop_father;

	  /* Walk the body of LOOP sorted by dominance relation.  Additionally,
	     if a basic block S dominates the latch, then only blocks dominated
	     by S are after it.
	     This is get_loop_body_in_dom_order using a worklist algorithm and
	     stopping once we are no longer interested in visiting further
	     blocks.  */
	  unsigned old_len = worklist.length ();
	  unsigned postpone = 0;
	  for (basic_block son = first_dom_son (CDI_DOMINATORS, bb);
	       son;
	       son = next_dom_son (CDI_DOMINATORS, son))
	    {
	      if (!flow_bb_inside_loop_p (loop, son))
		continue;
	      if (dominated_by_p (CDI_DOMINATORS, loop->latch, son))
		postpone = worklist.length ();
	      worklist.quick_push (son);
	    }
	  if (postpone)
	    /* Postponing the block that dominates the latch means
	       processing it last and thus putting it earliest in the
	       worklist.  */
	    std::swap (worklist[old_len], worklist[postpone]);
	}
      while (!worklist.is_empty ());

      while (1)
	{
	  if (dump_enabled_p ())
	    dump_printf (MSG_NOTE, "BB %d is always executed in loop %d\n",
			 last->index, loop->num);
	  SET_ALWAYS_EXECUTED_IN (last, loop);
	  if (last == loop->header)
	    break;
	  last = get_immediate_dominator (CDI_DOMINATORS, last);
	}
    }

  for (loop = loop->inner; loop; loop = loop->next)
    fill_always_executed_in_1 (loop, contains_call);
}

/* Fills ALWAYS_EXECUTED_IN information for basic blocks, i.e.
   for each such basic block bb records the outermost loop for that execution
   of its header implies execution of bb.  */

static void
fill_always_executed_in (void)
{
  basic_block bb;
  class loop *loop;

  auto_sbitmap contains_call (last_basic_block_for_fn (cfun));
  bitmap_clear (contains_call);
  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple_stmt_iterator gsi;
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  if (nonpure_call_p (gsi_stmt (gsi)))
	    break;
	}

      if (!gsi_end_p (gsi))
	bitmap_set_bit (contains_call, bb->index);
    }

  for (loop = current_loops->tree_root->inner; loop; loop = loop->next)
    fill_always_executed_in_1 (loop, contains_call);
}

/* Find the coldest loop preheader for LOOP, also find the nearest hotter loop
   to LOOP.  Then recursively iterate each inner loop.  */

void
fill_coldest_and_hotter_out_loop (class loop *coldest_loop,
				  class loop *hotter_loop, class loop *loop)
{
  if (bb_colder_than_loop_preheader (loop_preheader_edge (loop)->src,
				     coldest_loop))
    coldest_loop = loop;

  coldest_outermost_loop[loop->num] = coldest_loop;

  hotter_than_inner_loop[loop->num] = NULL;
  class loop *outer_loop = loop_outer (loop);
  if (hotter_loop
      && bb_colder_than_loop_preheader (loop_preheader_edge (loop)->src,
					hotter_loop))
    hotter_than_inner_loop[loop->num] = hotter_loop;

  if (outer_loop && outer_loop != current_loops->tree_root
      && bb_colder_than_loop_preheader (loop_preheader_edge (loop)->src,
					outer_loop))
    hotter_than_inner_loop[loop->num] = outer_loop;

  if (dump_enabled_p ())
    {
      dump_printf (MSG_NOTE, "loop %d's coldest_outermost_loop is %d, ",
		   loop->num, coldest_loop->num);
      if (hotter_than_inner_loop[loop->num])
	dump_printf (MSG_NOTE, "hotter_than_inner_loop is %d\n",
		     hotter_than_inner_loop[loop->num]->num);
      else
	dump_printf (MSG_NOTE, "hotter_than_inner_loop is NULL\n");
    }

  class loop *inner_loop;
  for (inner_loop = loop->inner; inner_loop; inner_loop = inner_loop->next)
    fill_coldest_and_hotter_out_loop (coldest_loop,
				      hotter_than_inner_loop[loop->num],
				      inner_loop);
}

/* Compute the global information needed by the loop invariant motion pass.  */

static void
tree_ssa_lim_initialize (bool store_motion)
{
  unsigned i;

  bitmap_obstack_initialize (&lim_bitmap_obstack);
  gcc_obstack_init (&mem_ref_obstack);
  lim_aux_data_map = new hash_map<gimple *, lim_aux_data *>;

  if (flag_tm)
    compute_transaction_bits ();

  memory_accesses.refs = new hash_table<mem_ref_hasher> (100);
  memory_accesses.refs_list.create (100);
  /* Allocate a special, unanalyzable mem-ref with ID zero.  */
  memory_accesses.refs_list.quick_push
    (mem_ref_alloc (NULL, 0, UNANALYZABLE_MEM_ID));

  memory_accesses.refs_loaded_in_loop.create (number_of_loops (cfun));
  memory_accesses.refs_loaded_in_loop.quick_grow (number_of_loops (cfun));
  memory_accesses.refs_stored_in_loop.create (number_of_loops (cfun));
  memory_accesses.refs_stored_in_loop.quick_grow (number_of_loops (cfun));
  if (store_motion)
    {
      memory_accesses.all_refs_stored_in_loop.create (number_of_loops (cfun));
      memory_accesses.all_refs_stored_in_loop.quick_grow
						      (number_of_loops (cfun));
    }

  for (i = 0; i < number_of_loops (cfun); i++)
    {
      bitmap_initialize (&memory_accesses.refs_loaded_in_loop[i],
			 &lim_bitmap_obstack);
      bitmap_initialize (&memory_accesses.refs_stored_in_loop[i],
			 &lim_bitmap_obstack);
      if (store_motion)
	bitmap_initialize (&memory_accesses.all_refs_stored_in_loop[i],
			   &lim_bitmap_obstack);
    }

  memory_accesses.ttae_cache = NULL;

  /* Initialize bb_loop_postorder with a mapping from loop->num to
     its postorder index.  */
  i = 0;
  bb_loop_postorder = XNEWVEC (unsigned, number_of_loops (cfun));
  for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
    bb_loop_postorder[loop->num] = i++;
}

/* Cleans up after the invariant motion pass.  */

static void
tree_ssa_lim_finalize (void)
{
  basic_block bb;
  unsigned i;
  im_mem_ref *ref;

  FOR_EACH_BB_FN (bb, cfun)
    SET_ALWAYS_EXECUTED_IN (bb, NULL);

  bitmap_obstack_release (&lim_bitmap_obstack);
  delete lim_aux_data_map;

  delete memory_accesses.refs;
  memory_accesses.refs = NULL;

  FOR_EACH_VEC_ELT (memory_accesses.refs_list, i, ref)
    memref_free (ref);
  memory_accesses.refs_list.release ();
  obstack_free (&mem_ref_obstack, NULL);

  memory_accesses.refs_loaded_in_loop.release ();
  memory_accesses.refs_stored_in_loop.release ();
  memory_accesses.all_refs_stored_in_loop.release ();

  if (memory_accesses.ttae_cache)
    free_affine_expand_cache (&memory_accesses.ttae_cache);

  free (bb_loop_postorder);

  coldest_outermost_loop.release ();
  hotter_than_inner_loop.release ();
}

/* Moves invariants from loops.  Only "expensive" invariants are moved out --
   i.e. those that are likely to be win regardless of the register pressure.
   Only perform store motion if STORE_MOTION is true.  */

unsigned int
loop_invariant_motion_in_fun (function *fun, bool store_motion)
{
  unsigned int todo = 0;

  tree_ssa_lim_initialize (store_motion);

  /* Gathers information about memory accesses in the loops.  */
  analyze_memory_references (store_motion);

  /* Fills ALWAYS_EXECUTED_IN information for basic blocks.  */
  fill_always_executed_in ();

  /* Pre-compute coldest outermost loop and nearest hotter loop of each loop.
   */
  class loop *loop;
  coldest_outermost_loop.create (number_of_loops (cfun));
  coldest_outermost_loop.safe_grow_cleared (number_of_loops (cfun));
  hotter_than_inner_loop.create (number_of_loops (cfun));
  hotter_than_inner_loop.safe_grow_cleared (number_of_loops (cfun));
  for (loop = current_loops->tree_root->inner; loop != NULL; loop = loop->next)
    fill_coldest_and_hotter_out_loop (loop, NULL, loop);

  int *rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
  int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);

  /* For each statement determine the outermost loop in that it is
     invariant and cost for computing the invariant.  */
  for (int i = 0; i < n; ++i)
    compute_invariantness (BASIC_BLOCK_FOR_FN (fun, rpo[i]));

  /* Execute store motion.  Force the necessary invariants to be moved
     out of the loops as well.  */
  if (store_motion)
    do_store_motion ();

  free (rpo);
  rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
  n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);

  /* Move the expressions that are expensive enough.  */
  for (int i = 0; i < n; ++i)
    todo |= move_computations_worker (BASIC_BLOCK_FOR_FN (fun, rpo[i]));

  free (rpo);

  gsi_commit_edge_inserts ();
  if (need_ssa_update_p (fun))
    rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);

  tree_ssa_lim_finalize ();

  return todo;
}

/* Loop invariant motion pass.  */

namespace {

const pass_data pass_data_lim =
{
  GIMPLE_PASS, /* type */
  "lim", /* name */
  OPTGROUP_LOOP, /* optinfo_flags */
  TV_LIM, /* tv_id */
  PROP_cfg, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_lim : public gimple_opt_pass
{
public:
  pass_lim (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_lim, ctxt)
  {}

  /* opt_pass methods: */
  opt_pass * clone () final override { return new pass_lim (m_ctxt); }
  bool gate (function *) final override { return flag_tree_loop_im != 0; }
  unsigned int execute (function *) final override;

}; // class pass_lim

unsigned int
pass_lim::execute (function *fun)
{
  bool in_loop_pipeline = scev_initialized_p ();
  if (!in_loop_pipeline)
    loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);

  if (number_of_loops (fun) <= 1)
    return 0;
  unsigned int todo = loop_invariant_motion_in_fun (fun, flag_move_loop_stores);

  if (!in_loop_pipeline)
    loop_optimizer_finalize ();
  else
    scev_reset ();
  return todo;
}

} // anon namespace

gimple_opt_pass *
make_pass_lim (gcc::context *ctxt)
{
  return new pass_lim (ctxt);
}


