/* Detection of Static Control Parts (SCoP) for Graphite.
   Copyright (C) 2009-2017 Free Software Foundation, Inc.
   Contributed by Sebastian Pop <sebastian.pop@amd.com> and
   Tobias Grosser <grosser@fim.uni-passau.de>.

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

#define USES_ISL

#include "config.h"

#ifdef HAVE_isl

#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "cfghooks.h"
#include "domwalk.h"
#include "params.h"
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop.h"
#include "tree-into-ssa.h"
#include "tree-ssa.h"
#include "cfgloop.h"
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
#include "gimple-pretty-print.h"
#include "graphite.h"

class debug_printer
{
private:
  FILE *dump_file;

public:
  void
  set_dump_file (FILE *f)
  {
    gcc_assert (f);
    dump_file = f;
  }

  friend debug_printer &
  operator<< (debug_printer &output, int i)
  {
    fprintf (output.dump_file, "%d", i);
    return output;
  }
  friend debug_printer &
  operator<< (debug_printer &output, const char *s)
  {
    fprintf (output.dump_file, "%s", s);
    return output;
  }
} dp;

#define DEBUG_PRINT(args) do \
    {								\
      if (dump_file && (dump_flags & TDF_DETAILS)) { args; }	\
    } while (0);

/* Pretty print to FILE all the SCoPs in DOT format and mark them with
   different colors.  If there are not enough colors, paint the
   remaining SCoPs in gray.

   Special nodes:
   - "*" after the node number denotes the entry of a SCoP,
   - "#" after the node number denotes the exit of a SCoP,
   - "()" around the node number denotes the entry or the
     exit nodes of the SCOP.  These are not part of SCoP.  */

DEBUG_FUNCTION void
dot_all_sese (FILE *file, vec<sese_l>& scops)
{
  /* Disable debugging while printing graph.  */
  int tmp_dump_flags = dump_flags;
  dump_flags = 0;

  fprintf (file, "digraph all {\n");

  basic_block bb;
  FOR_ALL_BB_FN (bb, cfun)
    {
      int part_of_scop = false;

      /* Use HTML for every bb label.  So we are able to print bbs
	 which are part of two different SCoPs, with two different
	 background colors.  */
      fprintf (file, "%d [label=<\n  <TABLE BORDER=\"0\" CELLBORDER=\"1\" ",
	       bb->index);
      fprintf (file, "CELLSPACING=\"0\">\n");

      /* Select color for SCoP.  */
      sese_l *region;
      int i;
      FOR_EACH_VEC_ELT (scops, i, region)
	{
	  bool sese_in_region = bb_in_sese_p (bb, *region);
	  if (sese_in_region || (region->exit->dest == bb)
	      || (region->entry->dest == bb))
	    {
	      const char *color;
	      switch (i % 17)
		{
		case 0: /* red */
		  color = "#e41a1c";
		  break;
		case 1: /* blue */
		  color = "#377eb8";
		  break;
		case 2: /* green */
		  color = "#4daf4a";
		  break;
		case 3: /* purple */
		  color = "#984ea3";
		  break;
		case 4: /* orange */
		  color = "#ff7f00";
		  break;
		case 5: /* yellow */
		  color = "#ffff33";
		  break;
		case 6: /* brown */
		  color = "#a65628";
		  break;
		case 7: /* rose */
		  color = "#f781bf";
		  break;
		case 8:
		  color = "#8dd3c7";
		  break;
		case 9:
		  color = "#ffffb3";
		  break;
		case 10:
		  color = "#bebada";
		  break;
		case 11:
		  color = "#fb8072";
		  break;
		case 12:
		  color = "#80b1d3";
		  break;
		case 13:
		  color = "#fdb462";
		  break;
		case 14:
		  color = "#b3de69";
		  break;
		case 15:
		  color = "#fccde5";
		  break;
		case 16:
		  color = "#bc80bd";
		  break;
		default: /* gray */
		  color = "#999999";
		}

	      fprintf (file, "    <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">",
		       color);

	      if (!sese_in_region)
		fprintf (file, " (");

	      if (bb == region->entry->dest && bb == region->exit->dest)
		fprintf (file, " %d*# ", bb->index);
	      else if (bb == region->entry->dest)
		fprintf (file, " %d* ", bb->index);
	      else if (bb == region->exit->dest)
		fprintf (file, " %d# ", bb->index);
	      else
		fprintf (file, " %d ", bb->index);

	      fprintf (file, "{lp_%d}", bb->loop_father->num);

	      if (!sese_in_region)
		fprintf (file, ")");

	      fprintf (file, "</TD></TR>\n");
	      part_of_scop = true;
	    }
	}

	if (!part_of_scop)
	  {
	    fprintf (file, "    <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">");
	    fprintf (file, " %d {lp_%d} </TD></TR>\n", bb->index,
		     bb->loop_father->num);
	  }
	fprintf (file, "  </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
    }

    FOR_ALL_BB_FN (bb, cfun)
      {
	edge e;
	edge_iterator ei;
	FOR_EACH_EDGE (e, ei, bb->succs)
	  fprintf (file, "%d -> %d;\n", bb->index, e->dest->index);
      }

  fputs ("}\n\n", file);

  /* Enable debugging again.  */
  dump_flags = tmp_dump_flags;
}

/* Display SCoP on stderr.  */

DEBUG_FUNCTION void
dot_sese (sese_l& scop)
{
  vec<sese_l> scops;
  scops.create (1);

  if (scop)
    scops.safe_push (scop);

  dot_all_sese (stderr, scops);

  scops.release ();
}

DEBUG_FUNCTION void
dot_cfg ()
{
  vec<sese_l> scops;
  scops.create (1);
  dot_all_sese (stderr, scops);
  scops.release ();
}

/* Return true if BB is empty, contains only DEBUG_INSNs.  */

static bool
trivially_empty_bb_p (basic_block bb)
{
  gimple_stmt_iterator gsi;

  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    if (gimple_code (gsi_stmt (gsi)) != GIMPLE_DEBUG)
      return false;

  return true;
}

/* Returns true when P1 and P2 are close phis with the same
   argument.  */

static inline bool
same_close_phi_node (gphi *p1, gphi *p2)
{
  return (types_compatible_p (TREE_TYPE (gimple_phi_result (p1)),
			      TREE_TYPE (gimple_phi_result (p2)))
	  && operand_equal_p (gimple_phi_arg_def (p1, 0),
			      gimple_phi_arg_def (p2, 0), 0));
}

static void make_close_phi_nodes_unique (basic_block bb);

/* Remove the close phi node at GSI and replace its rhs with the rhs
   of PHI.  */

static void
remove_duplicate_close_phi (gphi *phi, gphi_iterator *gsi)
{
  gimple *use_stmt;
  use_operand_p use_p;
  imm_use_iterator imm_iter;
  tree res = gimple_phi_result (phi);
  tree def = gimple_phi_result (gsi->phi ());

  gcc_assert (same_close_phi_node (phi, gsi->phi ()));

  FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
    {
      FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
	SET_USE (use_p, res);

      update_stmt (use_stmt);

      /* It is possible that we just created a duplicate close-phi
	 for an already-processed containing loop.  Check for this
	 case and clean it up.  */
      if (gimple_code (use_stmt) == GIMPLE_PHI
	  && gimple_phi_num_args (use_stmt) == 1)
	make_close_phi_nodes_unique (gimple_bb (use_stmt));
    }

  remove_phi_node (gsi, true);
}

/* Removes all the close phi duplicates from BB.  */

static void
make_close_phi_nodes_unique (basic_block bb)
{
  gphi_iterator psi;

  for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
    {
      gphi_iterator gsi = psi;
      gphi *phi = psi.phi ();

      /* At this point, PHI should be a close phi in normal form.  */
      gcc_assert (gimple_phi_num_args (phi) == 1);

      /* Iterate over the next phis and remove duplicates.  */
      gsi_next (&gsi);
      while (!gsi_end_p (gsi))
	if (same_close_phi_node (phi, gsi.phi ()))
	  remove_duplicate_close_phi (phi, &gsi);
	else
	  gsi_next (&gsi);
    }
}

/* Return true when NAME is defined in LOOP.  */

static bool
defined_in_loop_p (tree name, loop_p loop)
{
  gcc_assert (TREE_CODE (name) == SSA_NAME);
  return loop == loop_containing_stmt (SSA_NAME_DEF_STMT (name));
}

/* Transforms LOOP to the canonical loop closed SSA form.  */

static void
canonicalize_loop_closed_ssa (loop_p loop)
{
  edge e = single_exit (loop);
  basic_block bb;

  if (!e || e->flags & EDGE_ABNORMAL)
    return;

  bb = e->dest;

  if (single_pred_p (bb))
    {
      e = split_block_after_labels (bb);
      DEBUG_PRINT (dp << "Splitting bb_" << bb->index << ".\n");
      make_close_phi_nodes_unique (e->src);
    }
  else
    {
      gphi_iterator psi;
      basic_block close = split_edge (e);

      e = single_succ_edge (close);
      DEBUG_PRINT (dp << "Splitting edge (" << e->src->index << ","
		      << e->dest->index << ")\n");

      for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
	{
	  gphi *phi = psi.phi ();
	  unsigned i;

	  for (i = 0; i < gimple_phi_num_args (phi); i++)
	    if (gimple_phi_arg_edge (phi, i) == e)
	      {
		tree res, arg = gimple_phi_arg_def (phi, i);
		use_operand_p use_p;
		gphi *close_phi;

		/* Only add close phi nodes for SSA_NAMEs defined in LOOP.  */
		if (TREE_CODE (arg) != SSA_NAME
		    || !defined_in_loop_p (arg, loop))
		  continue;

		close_phi = create_phi_node (NULL_TREE, close);
		res = create_new_def_for (arg, close_phi,
					  gimple_phi_result_ptr (close_phi));
		add_phi_arg (close_phi, arg,
			     gimple_phi_arg_edge (close_phi, 0),
			     UNKNOWN_LOCATION);
		use_p = gimple_phi_arg_imm_use_ptr (phi, i);
		replace_exp (use_p, res);
		update_stmt (phi);
	      }
	}

      make_close_phi_nodes_unique (close);
    }

  /* The code above does not properly handle changes in the post dominance
     information (yet).  */
  recompute_all_dominators ();
}

/* Converts the current loop closed SSA form to a canonical form
   expected by the Graphite code generation.

   The loop closed SSA form has the following invariant: a variable
   defined in a loop that is used outside the loop appears only in the
   phi nodes in the destination of the loop exit.  These phi nodes are
   called close phi nodes.

   The canonical loop closed SSA form contains the extra invariants:

   - when the loop contains only one exit, the close phi nodes contain
   only one argument.  That implies that the basic block that contains
   the close phi nodes has only one predecessor, that is a basic block
   in the loop.

   - the basic block containing the close phi nodes does not contain
   other statements.

   - there exist only one phi node per definition in the loop.
*/

static void
canonicalize_loop_closed_ssa_form (void)
{
  checking_verify_loop_closed_ssa (true);

  loop_p loop;
  FOR_EACH_LOOP (loop, 0)
    canonicalize_loop_closed_ssa (loop);

  rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
  update_ssa (TODO_update_ssa);

  checking_verify_loop_closed_ssa (true);
}

/* Can all ivs be represented by a signed integer?
   As isl might generate negative values in its expressions, signed loop ivs
   are required in the backend.  */

static bool
loop_ivs_can_be_represented (loop_p loop)
{
  unsigned type_long_long = TYPE_PRECISION (long_long_integer_type_node);
  for (gphi_iterator psi = gsi_start_phis (loop->header); !gsi_end_p (psi);
       gsi_next (&psi))
    {
      gphi *phi = psi.phi ();
      tree res = PHI_RESULT (phi);
      tree type = TREE_TYPE (res);

      if (TYPE_UNSIGNED (type) && TYPE_PRECISION (type) >= type_long_long)
	return false;
    }

  return true;
}

/* Returns a COND_EXPR statement when BB has a single predecessor, the
   edge between BB and its predecessor is not a loop exit edge, and
   the last statement of the single predecessor is a COND_EXPR.  */

static gcond *
single_pred_cond_non_loop_exit (basic_block bb)
{
  if (single_pred_p (bb))
    {
      edge e = single_pred_edge (bb);
      basic_block pred = e->src;
      gimple *stmt;

      if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
	return NULL;

      stmt = last_stmt (pred);

      if (stmt && gimple_code (stmt) == GIMPLE_COND)
	return as_a<gcond *> (stmt);
    }

  return NULL;
}

namespace
{

/* Build the maximal scop containing LOOPs and add it to SCOPS.  */

class scop_detection
{
public:
  scop_detection () : scops (vNULL) {}

  ~scop_detection ()
  {
    scops.release ();
  }

  /* A marker for invalid sese_l.  */
  static sese_l invalid_sese;

  /* Return the SCOPS in this SCOP_DETECTION.  */

  vec<sese_l>
  get_scops ()
  {
    return scops;
  }

  /* Return an sese_l around the LOOP.  */

  sese_l get_sese (loop_p loop);

  /* Return the closest dominator with a single entry edge.  In case of a
     back-loop the back-edge is not counted.  */

  static edge get_nearest_dom_with_single_entry (basic_block dom);

  /* Return the closest post-dominator with a single exit edge.  In case of a
     back-loop the back-edge is not counted.  */

  static edge get_nearest_pdom_with_single_exit (basic_block dom);

  /* Merge scops at same loop depth and returns the new sese.
     Returns a new SESE when merge was successful, INVALID_SESE otherwise.  */

  sese_l merge_sese (sese_l first, sese_l second) const;

  /* Build scop outer->inner if possible.  */

  sese_l build_scop_depth (sese_l s, loop_p loop);

  /* If loop and loop->next are valid scops, try to merge them.  */

  sese_l build_scop_breadth (sese_l s1, loop_p loop);

  /* Return true when LOOP is a valid scop, that is a Static Control Part, a
     region of code that can be represented in the polyhedral model.  SCOP
     defines the region we analyse.  */

  bool loop_is_valid_in_scop (loop_p loop, sese_l scop) const;

  /* Return true when BEGIN is the preheader edge of a loop with a single exit
     END.  */

  static bool region_has_one_loop (sese_l s);

  /* Add to SCOPS a scop starting at SCOP_BEGIN and ending at SCOP_END.  */

  void add_scop (sese_l s);

  /* Returns true if S1 subsumes/surrounds S2.  */
  static bool subsumes (sese_l s1, sese_l s2);

  /* Remove a SCoP which is subsumed by S1.  */
  void remove_subscops (sese_l s1);

  /* Returns true if S1 intersects with S2.  Since we already know that S1 does
     not subsume S2 or vice-versa, we only check for entry bbs.  */

  static bool intersects (sese_l s1, sese_l s2);

  /* Remove one of the scops when it intersects with any other.  */

  void remove_intersecting_scops (sese_l s1);

  /* Return true when the body of LOOP has statements that can be represented
     as a valid scop.  */

  bool loop_body_is_valid_scop (loop_p loop, sese_l scop) const;

  /* Return true when BB contains a harmful operation for a scop: that
     can be a function call with side effects, the induction variables
     are not linear with respect to SCOP, etc.  The current open
     scop should end before this statement.  */

  bool harmful_stmt_in_bb (sese_l scop, basic_block bb) const;

  /* Return true when a statement in SCOP cannot be represented by Graphite.
     The assumptions are that L1 dominates L2, and SCOP->entry dominates L1.
     Limit the number of bbs between adjacent loops to
     PARAM_SCOP_MAX_NUM_BBS_BETWEEN_LOOPS.  */

  bool harmful_loop_in_region (sese_l scop) const;

  /* Return true only when STMT is simple enough for being handled by Graphite.
     This depends on SCOP, as the parameters are initialized relatively to
     this basic block, the linear functions are initialized based on the
     outermost loop containing STMT inside the SCOP.  BB is the place where we
     try to evaluate the STMT.  */

  bool stmt_simple_for_scop_p (sese_l scop, gimple *stmt,
			       basic_block bb) const;

  /* Something like "n * m" is not allowed.  */

  static bool graphite_can_represent_init (tree e);

  /* Return true when SCEV can be represented in the polyhedral model.

     An expression can be represented, if it can be expressed as an
     affine expression.  For loops (i, j) and parameters (m, n) all
     affine expressions are of the form:

     x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z

     1 i + 20 j + (-2) m + 25

     Something like "i * n" or "n * m" is not allowed.  */

  static bool graphite_can_represent_scev (tree scev);

  /* Return true when EXPR can be represented in the polyhedral model.

     This means an expression can be represented, if it is linear with respect
     to the loops and the strides are non parametric.  LOOP is the place where
     the expr will be evaluated.  SCOP defines the region we analyse.  */

  static bool graphite_can_represent_expr (sese_l scop, loop_p loop,
					   tree expr);

  /* Return true if the data references of STMT can be represented by Graphite.
     We try to analyze the data references in a loop contained in the SCOP.  */

  static bool stmt_has_simple_data_refs_p (sese_l scop, gimple *stmt);

  /* Remove the close phi node at GSI and replace its rhs with the rhs
     of PHI.  */

  static void remove_duplicate_close_phi (gphi *phi, gphi_iterator *gsi);

  /* Returns true when Graphite can represent LOOP in SCOP.
     FIXME: For the moment, graphite cannot be used on loops that iterate using
     induction variables that wrap.  */

  static bool can_represent_loop_1 (loop_p loop, sese_l scop);

  /* Return true when all the loops within LOOP can be represented by
     Graphite.  */

  static bool can_represent_loop (loop_p loop, sese_l scop);

  /* Returns the number of pbbs that are in loops contained in SCOP.  */

  static int nb_pbbs_in_loops (scop_p scop);

  static bool graphite_can_represent_stmt (sese_l, gimple *, basic_block);

private:
  vec<sese_l> scops;
};

sese_l scop_detection::invalid_sese (NULL, NULL);

/* Return an sese_l around the LOOP.  */

sese_l
scop_detection::get_sese (loop_p loop)
{
  if (!loop)
    return invalid_sese;

  if (!loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS))
    return invalid_sese;
  edge scop_end = single_exit (loop);
  if (!scop_end)
    return invalid_sese;
  edge scop_begin = loop_preheader_edge (loop);
  sese_l s (scop_begin, scop_end);
  return s;
}

/* Return the closest dominator with a single entry edge.  */

edge
scop_detection::get_nearest_dom_with_single_entry (basic_block dom)
{
  if (!dom->preds)
    return NULL;

  /* If any of the dominators has two predecessors but one of them is a back
     edge, then that basic block also qualifies as a dominator with single
     entry.  */
  if (dom->preds->length () == 2)
    {
      /* If e1->src dominates e2->src then e1->src will also dominate dom.  */
      edge e1 = (*dom->preds)[0];
      edge e2 = (*dom->preds)[1];
      loop_p l = dom->loop_father;
      loop_p l1 = e1->src->loop_father;
      loop_p l2 = e2->src->loop_father;
      if (l != l1 && l == l2
	  && dominated_by_p (CDI_DOMINATORS, e2->src, e1->src))
	return e1;
      if (l != l2 && l == l1
	  && dominated_by_p (CDI_DOMINATORS, e1->src, e2->src))
	return e2;
    }

  while (dom->preds->length () != 1)
    {
      if (dom->preds->length () < 1)
	return NULL;
      dom = get_immediate_dominator (CDI_DOMINATORS, dom);
      if (!dom->preds)
	return NULL;
    }
  return (*dom->preds)[0];
}

/* Return the closest post-dominator with a single exit edge.  In case of a
   back-loop the back-edge is not counted.  */

edge
scop_detection::get_nearest_pdom_with_single_exit (basic_block pdom)
{
  if (!pdom->succs)
    return NULL;

  /* If any of the post-dominators has two successors but one of them is a back
     edge, then that basic block also qualifies as a post-dominator with single
     exit. */
  if (pdom->succs->length () == 2)
    {
      /* If e1->dest post-dominates e2->dest then e1->dest will also
	 post-dominate pdom.  */
      edge e1 = (*pdom->succs)[0];
      edge e2 = (*pdom->succs)[1];
      loop_p l = pdom->loop_father;
      loop_p l1 = e1->dest->loop_father;
      loop_p l2 = e2->dest->loop_father;
      if (l != l1 && l == l2
	  && dominated_by_p (CDI_POST_DOMINATORS, e2->dest, e1->dest))
	return e1;
      if (l != l2 && l == l1
	  && dominated_by_p (CDI_POST_DOMINATORS, e1->dest, e2->dest))
	return e2;
    }

  while (pdom->succs->length () != 1)
    {
      if (pdom->succs->length () < 1)
	return NULL;
      pdom = get_immediate_dominator (CDI_POST_DOMINATORS, pdom);
      if (!pdom->succs)
	return NULL;
    }

  return (*pdom->succs)[0];
}

/* Merge scops at same loop depth and returns the new sese.
   Returns a new SESE when merge was successful, INVALID_SESE otherwise.  */

sese_l
scop_detection::merge_sese (sese_l first, sese_l second) const
{
  /* In the trivial case first/second may be NULL.  */
  if (!first)
    return second;
  if (!second)
    return first;

  DEBUG_PRINT (dp << "[scop-detection] try merging sese s1: ";
	       print_sese (dump_file, first);
	       dp << "[scop-detection] try merging sese s2: ";
	       print_sese (dump_file, second));

  /* Assumption: Both the sese's should be at the same loop depth or one scop
     should subsume the other like in case of nested loops.  */

  /* Find the common dominators for entry,
     and common post-dominators for the exit.  */
  basic_block dom = nearest_common_dominator (CDI_DOMINATORS,
					      get_entry_bb (first),
					      get_entry_bb (second));

  edge entry = get_nearest_dom_with_single_entry (dom);

  if (!entry || (entry->flags & EDGE_IRREDUCIBLE_LOOP))
    return invalid_sese;

  basic_block pdom = nearest_common_dominator (CDI_POST_DOMINATORS,
					       get_exit_bb (first),
					       get_exit_bb (second));
  pdom = nearest_common_dominator (CDI_POST_DOMINATORS, dom, pdom);

  edge exit = get_nearest_pdom_with_single_exit (pdom);

  if (!exit || (exit->flags & EDGE_IRREDUCIBLE_LOOP))
    return invalid_sese;

  sese_l combined (entry, exit);

  DEBUG_PRINT (dp << "[scop-detection] checking combined sese: ";
	       print_sese (dump_file, combined));

  /* FIXME: We could iterate to find the dom which dominates pdom, and pdom
     which post-dominates dom, until it stabilizes.  Also, ENTRY->SRC and
     EXIT->DEST should be in the same loop nest.  */
  if (!dominated_by_p (CDI_DOMINATORS, pdom, dom)
      || loop_depth (entry->src->loop_father)
	 != loop_depth (exit->dest->loop_father))
    return invalid_sese;

  /* For now we just bail out when there is a loop exit in the region
     that is not also the exit of the region.  We could enlarge the
     region to cover the loop that region exits to.  See PR79977.  */
  if (loop_outer (entry->src->loop_father))
    {
      vec<edge> exits = get_loop_exit_edges (entry->src->loop_father);
      for (unsigned i = 0; i < exits.length (); ++i)
	{
	  if (exits[i] != exit
	      && bb_in_region (exits[i]->src, entry->dest, exit->src))
	    {
	      DEBUG_PRINT (dp << "[scop-detection-fail] cannot merge seses.\n");
	      exits.release ();
	      return invalid_sese;
	    }
	}
      exits.release ();
    }

  /* For now we just want to bail out when exit does not post-dominate entry.
     TODO: We might just add a basic_block at the exit to make exit
     post-dominate entry (the entire region).  */
  if (!dominated_by_p (CDI_POST_DOMINATORS, get_entry_bb (combined),
		       get_exit_bb (combined))
      || !dominated_by_p (CDI_DOMINATORS, get_exit_bb (combined),
			  get_entry_bb (combined)))
    {
      DEBUG_PRINT (dp << "[scop-detection-fail] cannot merge seses.\n");
      return invalid_sese;
    }

  /* FIXME: We should remove this piece of code once
     canonicalize_loop_closed_ssa has been removed, because that function
     adds a BB with single exit.  */
  if (!trivially_empty_bb_p (get_exit_bb (combined)))
    {
      /* Find the first empty succ (with single exit) of combined.exit.  */
      basic_block imm_succ = combined.exit->dest;
      if (single_succ_p (imm_succ)
	  && single_pred_p (imm_succ)
	  && trivially_empty_bb_p (imm_succ))
	combined.exit = single_succ_edge (imm_succ);
      else
	{
	  DEBUG_PRINT (dp << "[scop-detection-fail] Discarding SCoP because "
			  << "no single exit (empty succ) for sese exit";
		       print_sese (dump_file, combined));
	  return invalid_sese;
	}
    }

  /* Analyze all the BBs in new sese.  */
  if (harmful_loop_in_region (combined))
    return invalid_sese;

  DEBUG_PRINT (dp << "[merged-sese] s1: "; print_sese (dump_file, combined));

  return combined;
}

/* Build scop outer->inner if possible.  */

sese_l
scop_detection::build_scop_depth (sese_l s, loop_p loop)
{
  if (!loop)
    return s;

  DEBUG_PRINT (dp << "[Depth loop_" << loop->num << "]\n");
  s = build_scop_depth (s, loop->inner);

  sese_l s2 = merge_sese (s, get_sese (loop));
  if (!s2)
    {
      /* s might be a valid scop, so return it and start analyzing from the
	 adjacent loop.  */
      build_scop_depth (invalid_sese, loop->next);
      return s;
    }

  if (!loop_is_valid_in_scop (loop, s2))
    return build_scop_depth (invalid_sese, loop->next);

  return build_scop_breadth (s2, loop);
}

/* If loop and loop->next are valid scops, try to merge them.  */

sese_l
scop_detection::build_scop_breadth (sese_l s1, loop_p loop)
{
  if (!loop)
    return s1;
  DEBUG_PRINT (dp << "[Breadth loop_" << loop->num << "]\n");
  gcc_assert (s1);

  loop_p l = loop;
  sese_l s2 = build_scop_depth (invalid_sese, l->next);
  if (!s2)
    {
      if (s1)
	add_scop (s1);
      return s1;
    }

  sese_l combined = merge_sese (s1, s2);

  /* Combining adjacent loops may add unrelated loops into the
     region so we have to check all sub-loops of the outer loop
     that are in the combined region.  */
  if (combined)
    for (l = loop_outer (loop)->inner; l; l = l->next)
      if (bb_in_sese_p (l->header, combined)
	  && ! loop_is_valid_in_scop (l, combined))
	{
	  combined = invalid_sese;
	  break;
	}

  if (combined)
    s1 = combined;
  else
    add_scop (s2);

  if (s1)
    add_scop (s1);
  return s1;
}

/* Returns true when Graphite can represent LOOP in SCOP.
   FIXME: For the moment, graphite cannot be used on loops that iterate using
   induction variables that wrap.  */

bool
scop_detection::can_represent_loop_1 (loop_p loop, sese_l scop)
{
  tree niter;
  struct tree_niter_desc niter_desc;

  return single_exit (loop)
    && !(loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP)
    && number_of_iterations_exit (loop, single_exit (loop), &niter_desc, false)
    && niter_desc.control.no_overflow
    && (niter = number_of_latch_executions (loop))
    && !chrec_contains_undetermined (niter)
    && !chrec_contains_undetermined (scalar_evolution_in_region (scop,
								 loop, niter))
    && graphite_can_represent_expr (scop, loop, niter);
}

/* Return true when all the loops within LOOP can be represented by
   Graphite.  */

bool
scop_detection::can_represent_loop (loop_p loop, sese_l scop)
{
  if (!can_represent_loop_1 (loop, scop))
    return false;
  if (loop->inner && !can_represent_loop (loop->inner, scop))
    return false;
  if (loop->next && !can_represent_loop (loop->next, scop))
    return false;

  return true;
}

/* Return true when LOOP is a valid scop, that is a Static Control Part, a
   region of code that can be represented in the polyhedral model.  SCOP
   defines the region we analyse.  */

bool
scop_detection::loop_is_valid_in_scop (loop_p loop, sese_l scop) const
{
  if (!scop)
    return false;

  if (!optimize_loop_nest_for_speed_p (loop))
    {
      DEBUG_PRINT (dp << "[scop-detection-fail] loop_"
		      << loop->num << " is not on a hot path.\n");
      return false;
    }

  if (!can_represent_loop (loop, scop))
    {
      DEBUG_PRINT (dp << "[scop-detection-fail] cannot represent loop_"
		      << loop->num << "\n");
      return false;
    }

  if (loop_body_is_valid_scop (loop, scop))
    {
      DEBUG_PRINT (dp << "[valid-scop] loop_" << loop->num
		      << " is a valid scop.\n");
      return true;
    }
  return false;
}

/* Return true when BEGIN is the preheader edge of a loop with a single exit
   END.  */

bool
scop_detection::region_has_one_loop (sese_l s)
{
  edge begin = s.entry;
  edge end = s.exit;
  /* Check for a single perfectly nested loop.  */
  if (begin->dest->loop_father->inner)
    return false;

  /* Otherwise, check whether we have adjacent loops.  */
  return begin->dest->loop_father == end->src->loop_father;
}

/* Add to SCOPS a scop starting at SCOP_BEGIN and ending at SCOP_END.  */

void
scop_detection::add_scop (sese_l s)
{
  gcc_assert (s);

  /* Do not add scops with only one loop.  */
  if (region_has_one_loop (s))
    {
      DEBUG_PRINT (dp << "[scop-detection-fail] Discarding one loop SCoP: ";
		   print_sese (dump_file, s));
      return;
    }

  if (get_exit_bb (s) == EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      DEBUG_PRINT (dp << "[scop-detection-fail] "
		      << "Discarding SCoP exiting to return: ";
		   print_sese (dump_file, s));
      return;
    }

  /* Remove all the scops which are subsumed by s.  */
  remove_subscops (s);

  /* Remove intersecting scops. FIXME: It will be a good idea to keep
     the non-intersecting part of the scop already in the list.  */
  remove_intersecting_scops (s);

  scops.safe_push (s);
  DEBUG_PRINT (dp << "[scop-detection] Adding SCoP: "; print_sese (dump_file, s));
}

/* Return true when a statement in SCOP cannot be represented by Graphite.
   The assumptions are that L1 dominates L2, and SCOP->entry dominates L1.
   Limit the number of bbs between adjacent loops to
   PARAM_SCOP_MAX_NUM_BBS_BETWEEN_LOOPS.  */

bool
scop_detection::harmful_loop_in_region (sese_l scop) const
{
  basic_block exit_bb = get_exit_bb (scop);
  basic_block entry_bb = get_entry_bb (scop);

  DEBUG_PRINT (dp << "[checking-harmful-bbs] ";
	       print_sese (dump_file, scop));
  gcc_assert (dominated_by_p (CDI_DOMINATORS, exit_bb, entry_bb));

  auto_vec<basic_block> worklist;
  auto_bitmap loops;

  worklist.safe_push (entry_bb);
  while (! worklist.is_empty ())
    {
      basic_block bb = worklist.pop ();
      DEBUG_PRINT (dp << "Visiting bb_" << bb->index << "\n");

      /* The basic block should not be part of an irreducible loop.  */
      if (bb->flags & BB_IRREDUCIBLE_LOOP)
	return true;

      /* Check for unstructured control flow: CFG not generated by structured
	 if-then-else.  */
      if (bb->succs->length () > 1)
	{
	  edge e;
	  edge_iterator ei;
	  FOR_EACH_EDGE (e, ei, bb->succs)
	    if (!dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest)
		&& !dominated_by_p (CDI_DOMINATORS, e->dest, bb))
	      return true;
	}

      /* Collect all loops in the current region.  */
      loop_p loop = bb->loop_father;
      if (loop_in_sese_p (loop, scop))
	bitmap_set_bit (loops, loop->num);
      else
	{
	  /* We only check for harmful statements in basic blocks not part of
	     any loop fully contained in the scop: other bbs are checked below
	     in loop_is_valid_in_scop.  */
	  if (harmful_stmt_in_bb (scop, bb))
	    return true;
	}

      if (bb != exit_bb)
	for (basic_block dom = first_dom_son (CDI_DOMINATORS, bb);
	     dom;
	     dom = next_dom_son (CDI_DOMINATORS, dom))
	  worklist.safe_push (dom);
    }

  /* Go through all loops and check that they are still valid in the combined
     scop.  */
  unsigned j;
  bitmap_iterator bi;
  EXECUTE_IF_SET_IN_BITMAP (loops, 0, j, bi)
    {
      loop_p loop = (*current_loops->larray)[j];
      gcc_assert (loop->num == (int) j);

      if (!loop_is_valid_in_scop (loop, scop))
	return true;
    }

  return false;
}

/* Returns true if S1 subsumes/surrounds S2.  */
bool
scop_detection::subsumes (sese_l s1, sese_l s2)
{
  if (dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2),
		      get_entry_bb (s1))
      && dominated_by_p (CDI_POST_DOMINATORS, s2.exit->dest,
			 s1.exit->dest))
    return true;
  return false;
}

/* Remove a SCoP which is subsumed by S1.  */
void
scop_detection::remove_subscops (sese_l s1)
{
  int j;
  sese_l *s2;
  FOR_EACH_VEC_ELT_REVERSE (scops, j, s2)
    {
      if (subsumes (s1, *s2))
	{
	  DEBUG_PRINT (dp << "Removing sub-SCoP";
		       print_sese (dump_file, *s2));
	  scops.unordered_remove (j);
	}
    }
}

/* Returns true if S1 intersects with S2.  Since we already know that S1 does
   not subsume S2 or vice-versa, we only check for entry bbs.  */

bool
scop_detection::intersects (sese_l s1, sese_l s2)
{
  if (dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2),
		      get_entry_bb (s1))
      && !dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2),
			  get_exit_bb (s1)))
    return true;
  if ((s1.exit == s2.entry) || (s2.exit == s1.entry))
    return true;

  return false;
}

/* Remove one of the scops when it intersects with any other.  */

void
scop_detection::remove_intersecting_scops (sese_l s1)
{
  int j;
  sese_l *s2;
  FOR_EACH_VEC_ELT_REVERSE (scops, j, s2)
    {
      if (intersects (s1, *s2))
	{
	  DEBUG_PRINT (dp << "Removing intersecting SCoP";
		       print_sese (dump_file, *s2);
		       dp << "Intersects with:";
		       print_sese (dump_file, s1));
	  scops.unordered_remove (j);
	}
    }
}

/* Something like "n * m" is not allowed.  */

bool
scop_detection::graphite_can_represent_init (tree e)
{
  switch (TREE_CODE (e))
    {
    case POLYNOMIAL_CHREC:
      return graphite_can_represent_init (CHREC_LEFT (e))
	&& graphite_can_represent_init (CHREC_RIGHT (e));

    case MULT_EXPR:
      if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
	return graphite_can_represent_init (TREE_OPERAND (e, 0))
	  && tree_fits_shwi_p (TREE_OPERAND (e, 1));
      else
	return graphite_can_represent_init (TREE_OPERAND (e, 1))
	  && tree_fits_shwi_p (TREE_OPERAND (e, 0));

    case PLUS_EXPR:
    case POINTER_PLUS_EXPR:
    case MINUS_EXPR:
      return graphite_can_represent_init (TREE_OPERAND (e, 0))
	&& graphite_can_represent_init (TREE_OPERAND (e, 1));

    case NEGATE_EXPR:
    case BIT_NOT_EXPR:
    CASE_CONVERT:
    case NON_LVALUE_EXPR:
      return graphite_can_represent_init (TREE_OPERAND (e, 0));

    default:
      break;
    }

  return true;
}

/* Return true when SCEV can be represented in the polyhedral model.

   An expression can be represented, if it can be expressed as an
   affine expression.  For loops (i, j) and parameters (m, n) all
   affine expressions are of the form:

   x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z

   1 i + 20 j + (-2) m + 25

   Something like "i * n" or "n * m" is not allowed.  */

bool
scop_detection::graphite_can_represent_scev (tree scev)
{
  if (chrec_contains_undetermined (scev))
    return false;

  /* We disable the handling of pointer types, because it’s currently not
     supported by Graphite with the isl AST generator. SSA_NAME nodes are
     the only nodes, which are disabled in case they are pointers to object
     types, but this can be changed.  */

  if (POINTER_TYPE_P (TREE_TYPE (scev)) && TREE_CODE (scev) == SSA_NAME)
    return false;

  switch (TREE_CODE (scev))
    {
    case NEGATE_EXPR:
    case BIT_NOT_EXPR:
    CASE_CONVERT:
    case NON_LVALUE_EXPR:
      return graphite_can_represent_scev (TREE_OPERAND (scev, 0));

    case PLUS_EXPR:
    case POINTER_PLUS_EXPR:
    case MINUS_EXPR:
      return graphite_can_represent_scev (TREE_OPERAND (scev, 0))
	&& graphite_can_represent_scev (TREE_OPERAND (scev, 1));

    case MULT_EXPR:
      return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 0)))
	&& !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 1)))
	&& !(chrec_contains_symbols (TREE_OPERAND (scev, 0))
	     && chrec_contains_symbols (TREE_OPERAND (scev, 1)))
	&& graphite_can_represent_init (scev)
	&& graphite_can_represent_scev (TREE_OPERAND (scev, 0))
	&& graphite_can_represent_scev (TREE_OPERAND (scev, 1));

    case POLYNOMIAL_CHREC:
      /* Check for constant strides.  With a non constant stride of
	 'n' we would have a value of 'iv * n'.  Also check that the
	 initial value can represented: for example 'n * m' cannot be
	 represented.  */
      if (!evolution_function_right_is_integer_cst (scev)
	  || !graphite_can_represent_init (scev))
	return false;
      return graphite_can_represent_scev (CHREC_LEFT (scev));

    default:
      break;
    }

  /* Only affine functions can be represented.  */
  if (tree_contains_chrecs (scev, NULL) || !scev_is_linear_expression (scev))
    return false;

  return true;
}

/* Return true when EXPR can be represented in the polyhedral model.

   This means an expression can be represented, if it is linear with respect to
   the loops and the strides are non parametric.  LOOP is the place where the
   expr will be evaluated.  SCOP defines the region we analyse.  */

bool
scop_detection::graphite_can_represent_expr (sese_l scop, loop_p loop,
					     tree expr)
{
  tree scev = scalar_evolution_in_region (scop, loop, expr);
  return graphite_can_represent_scev (scev);
}

/* Return true if the data references of STMT can be represented by Graphite.
   We try to analyze the data references in a loop contained in the SCOP.  */

bool
scop_detection::stmt_has_simple_data_refs_p (sese_l scop, gimple *stmt)
{
  loop_p nest = outermost_loop_in_sese (scop, gimple_bb (stmt));
  loop_p loop = loop_containing_stmt (stmt);
  vec<data_reference_p> drs = vNULL;

  graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);

  int j;
  data_reference_p dr;
  FOR_EACH_VEC_ELT (drs, j, dr)
    {
      int nb_subscripts = DR_NUM_DIMENSIONS (dr);

      if (nb_subscripts < 1)
	{
	  free_data_refs (drs);
	  return false;
	}

      tree ref = DR_REF (dr);

      for (int i = nb_subscripts - 1; i >= 0; i--)
	{
	  if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i))
	      || (TREE_CODE (ref) != ARRAY_REF && TREE_CODE (ref) != MEM_REF
		  && TREE_CODE (ref) != COMPONENT_REF))
	    {
	      free_data_refs (drs);
	      return false;
	    }

	  ref = TREE_OPERAND (ref, 0);
	}
    }

    free_data_refs (drs);
    return true;
}

/* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
   Calls have side-effects, except those to const or pure
   functions.  */

static bool
stmt_has_side_effects (gimple *stmt)
{
  if (gimple_has_volatile_ops (stmt)
      || (gimple_code (stmt) == GIMPLE_CALL
	  && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
      || (gimple_code (stmt) == GIMPLE_ASM))
    {
      DEBUG_PRINT (dp << "[scop-detection-fail] "
		      << "Statement has side-effects:\n";
	print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_MEMSYMS));
      return true;
    }
  return false;
}

/* Returns true if STMT can be represented in polyhedral model. LABEL,
   simple COND stmts, pure calls, and assignments can be repesented.  */

bool
scop_detection::graphite_can_represent_stmt (sese_l scop, gimple *stmt,
					     basic_block bb)
{
  loop_p loop = bb->loop_father;
  switch (gimple_code (stmt))
    {
    case GIMPLE_LABEL:
      return true;

    case GIMPLE_COND:
      {
	/* We can handle all binary comparisons.  Inequalities are
	   also supported as they can be represented with union of
	   polyhedra.  */
	enum tree_code code = gimple_cond_code (stmt);
	if (!(code == LT_EXPR
	      || code == GT_EXPR
	      || code == LE_EXPR
	      || code == GE_EXPR
	      || code == EQ_EXPR
	      || code == NE_EXPR))
	  {
	    DEBUG_PRINT (dp << "[scop-detection-fail] "
			    << "Graphite cannot handle cond stmt:\n";
			 print_gimple_stmt (dump_file, stmt, 0,
					    TDF_VOPS | TDF_MEMSYMS));
	    return false;
	  }

	for (unsigned i = 0; i < 2; ++i)
	  {
	    tree op = gimple_op (stmt, i);
	    if (!graphite_can_represent_expr (scop, loop, op)
		/* We can only constrain on integer type.  */
		|| (TREE_CODE (TREE_TYPE (op)) != INTEGER_TYPE))
	      {
		DEBUG_PRINT (dp << "[scop-detection-fail] "
				<< "Graphite cannot represent stmt:\n";
			     print_gimple_stmt (dump_file, stmt, 0,
						TDF_VOPS | TDF_MEMSYMS));
		return false;
	      }
	  }

	return true;
      }

    case GIMPLE_ASSIGN:
    case GIMPLE_CALL:
      return true;

    default:
      /* These nodes cut a new scope.  */
      DEBUG_PRINT (
	  dp << "[scop-detection-fail] "
	     << "Gimple stmt not handled in Graphite:\n";
	  print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_MEMSYMS));
      return false;
    }
}

/* Return true only when STMT is simple enough for being handled by Graphite.
   This depends on SCOP, as the parameters are initialized relatively to
   this basic block, the linear functions are initialized based on the outermost
   loop containing STMT inside the SCOP.  BB is the place where we try to
   evaluate the STMT.  */

bool
scop_detection::stmt_simple_for_scop_p (sese_l scop, gimple *stmt,
					basic_block bb) const
{
  gcc_assert (scop);

  if (is_gimple_debug (stmt))
    return true;

  if (stmt_has_side_effects (stmt))
    return false;

  if (!stmt_has_simple_data_refs_p (scop, stmt))
    {
      DEBUG_PRINT (dp << "[scop-detection-fail] "
		      << "Graphite cannot handle data-refs in stmt:\n";
	print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS|TDF_MEMSYMS););
      return false;
    }

  return graphite_can_represent_stmt (scop, stmt, bb);
}

/* Return true when BB contains a harmful operation for a scop: that
   can be a function call with side effects, the induction variables
   are not linear with respect to SCOP, etc.  The current open
   scop should end before this statement.  */

bool
scop_detection::harmful_stmt_in_bb (sese_l scop, basic_block bb) const
{
  gimple_stmt_iterator gsi;

  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    if (!stmt_simple_for_scop_p (scop, gsi_stmt (gsi), bb))
      return true;

  return false;
}

/* Return true when the body of LOOP has statements that can be represented as a
   valid scop.  */

bool
scop_detection::loop_body_is_valid_scop (loop_p loop, sese_l scop) const
{
  if (!loop_ivs_can_be_represented (loop))
    {
      DEBUG_PRINT (dp << "[scop-detection-fail] loop_" << loop->num
		      << "IV cannot be represented.\n");
      return false;
    }

  if (!loop_nest_has_data_refs (loop))
    {
      DEBUG_PRINT (dp << "[scop-detection-fail] loop_" << loop->num
		      << "does not have any data reference.\n");
      return false;
    }

  basic_block *bbs = get_loop_body (loop);
  for (unsigned i = 0; i < loop->num_nodes; i++)
    {
      basic_block bb = bbs[i];

      if (harmful_stmt_in_bb (scop, bb))
	{
	  free (bbs);
	  return false;
	}
    }
  free (bbs);

  if (loop->inner)
    {
      loop = loop->inner;
      while (loop)
	{
	  if (!loop_body_is_valid_scop (loop, scop))
	    return false;
	  loop = loop->next;
	}
    }

  return true;
}

/* Returns the number of pbbs that are in loops contained in SCOP.  */

int
scop_detection::nb_pbbs_in_loops (scop_p scop)
{
  int i;
  poly_bb_p pbb;
  int res = 0;

  FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
    if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), scop->scop_info->region))
      res++;

  return res;
}

/* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
   Otherwise returns -1.  */

static inline int
parameter_index_in_region_1 (tree name, sese_info_p region)
{
  int i;
  tree p;

  gcc_assert (TREE_CODE (name) == SSA_NAME);

  FOR_EACH_VEC_ELT (region->params, i, p)
    if (p == name)
      return i;

  return -1;
}

/* When the parameter NAME is in REGION, returns its index in
   SESE_PARAMS.  Otherwise this function inserts NAME in SESE_PARAMS
   and returns the index of NAME.  */

static int
parameter_index_in_region (tree name, sese_info_p region)
{
  int i;

  gcc_assert (TREE_CODE (name) == SSA_NAME);

  /* Cannot constrain on anything else than INTEGER_TYPE parameters.  */
  if (TREE_CODE (TREE_TYPE (name)) != INTEGER_TYPE)
    return -1;

  if (!invariant_in_sese_p_rec (name, region->region, NULL))
    return -1;

  i = parameter_index_in_region_1 (name, region);
  if (i != -1)
    return i;

  i = region->params.length ();
  region->params.safe_push (name);
  return i;
}

/* In the context of sese S, scan the expression E and translate it to
   a linear expression C.  When parsing a symbolic multiplication, K
   represents the constant multiplier of an expression containing
   parameters.  */

static void
scan_tree_for_params (sese_info_p s, tree e)
{
  if (e == chrec_dont_know)
    return;

  switch (TREE_CODE (e))
    {
    case POLYNOMIAL_CHREC:
      scan_tree_for_params (s, CHREC_LEFT (e));
      break;

    case MULT_EXPR:
      if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
	scan_tree_for_params (s, TREE_OPERAND (e, 0));
      else
	scan_tree_for_params (s, TREE_OPERAND (e, 1));
      break;

    case PLUS_EXPR:
    case POINTER_PLUS_EXPR:
    case MINUS_EXPR:
      scan_tree_for_params (s, TREE_OPERAND (e, 0));
      scan_tree_for_params (s, TREE_OPERAND (e, 1));
      break;

    case NEGATE_EXPR:
    case BIT_NOT_EXPR:
    CASE_CONVERT:
    case NON_LVALUE_EXPR:
      scan_tree_for_params (s, TREE_OPERAND (e, 0));
      break;

    case SSA_NAME:
      parameter_index_in_region (e, s);
      break;

    case INTEGER_CST:
    case ADDR_EXPR:
    case REAL_CST:
    case COMPLEX_CST:
    case VECTOR_CST:
      break;

   default:
      gcc_unreachable ();
      break;
    }
}

/* Find parameters with respect to REGION in BB. We are looking in memory
   access functions, conditions and loop bounds.  */

static void
find_params_in_bb (sese_info_p region, gimple_poly_bb_p gbb)
{
  /* Find parameters in the access functions of data references.  */
  int i;
  data_reference_p dr;
  FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
    for (unsigned j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
      scan_tree_for_params (region, DR_ACCESS_FN (dr, j));

  /* Find parameters in conditional statements.  */
  gimple *stmt;
  loop_p loop = GBB_BB (gbb)->loop_father;
  FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
    {
      tree lhs = scalar_evolution_in_region (region->region, loop,
					     gimple_cond_lhs (stmt));
      tree rhs = scalar_evolution_in_region (region->region, loop,
					     gimple_cond_rhs (stmt));

      scan_tree_for_params (region, lhs);
      scan_tree_for_params (region, rhs);
    }
}

/* Record the parameters used in the SCOP.  A variable is a parameter
   in a scop if it does not vary during the execution of that scop.  */

static void
find_scop_parameters (scop_p scop)
{
  unsigned i;
  sese_info_p region = scop->scop_info;
  struct loop *loop;

  /* Find the parameters used in the loop bounds.  */
  FOR_EACH_VEC_ELT (region->loop_nest, i, loop)
    {
      tree nb_iters = number_of_latch_executions (loop);

      if (!chrec_contains_symbols (nb_iters))
	continue;

      nb_iters = scalar_evolution_in_region (region->region, loop, nb_iters);
      scan_tree_for_params (region, nb_iters);
    }

  /* Find the parameters used in data accesses.  */
  poly_bb_p pbb;
  FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
    find_params_in_bb (region, PBB_BLACK_BOX (pbb));

  int nbp = sese_nb_params (region);
  scop_set_nb_params (scop, nbp);
}

/* Record DEF if it is used in other bbs different than DEF_BB in the SCOP.  */

static void
build_cross_bb_scalars_def (scop_p scop, tree def, basic_block def_bb,
			     vec<tree> *writes)
{
  if (!def || !is_gimple_reg (def))
    return;

  /* Do not gather scalar variables that can be analyzed by SCEV as they can be
     generated out of the induction variables.  */
  if (scev_analyzable_p (def, scop->scop_info->region))
    return;

  gimple *use_stmt;
  imm_use_iterator imm_iter;
  FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
    if (def_bb != gimple_bb (use_stmt) && !is_gimple_debug (use_stmt))
      {
	writes->safe_push (def);
	DEBUG_PRINT (dp << "Adding scalar write: ";
		     print_generic_expr (dump_file, def, 0);
		     dp << "\nFrom stmt: ";
		     print_gimple_stmt (dump_file,
					SSA_NAME_DEF_STMT (def), 0, 0));
	/* This is required by the FOR_EACH_IMM_USE_STMT when we want to break
	   before all the uses have been visited.  */
	BREAK_FROM_IMM_USE_STMT (imm_iter);
      }
}

/* Record DEF if it is used in other bbs different than DEF_BB in the SCOP.  */

static void
build_cross_bb_scalars_use (scop_p scop, tree use, gimple *use_stmt,
			    vec<scalar_use> *reads)
{
  gcc_assert (use);
  if (!is_gimple_reg (use))
    return;

  /* Do not gather scalar variables that can be analyzed by SCEV as they can be
     generated out of the induction variables.  */
  if (scev_analyzable_p (use, scop->scop_info->region))
    return;

  gimple *def_stmt = SSA_NAME_DEF_STMT (use);
  if (gimple_bb (def_stmt) != gimple_bb (use_stmt))
    {
      DEBUG_PRINT (dp << "Adding scalar read: ";
		   print_generic_expr (dump_file, use, 0);
		   dp << "\nFrom stmt: ";
		   print_gimple_stmt (dump_file, use_stmt, 0, 0));
      reads->safe_push (std::make_pair (use_stmt, use));
    }
}

/* Record all scalar variables that are defined and used in different BBs of the
   SCOP.  */

static void
graphite_find_cross_bb_scalar_vars (scop_p scop, gimple *stmt,
				    vec<scalar_use> *reads, vec<tree> *writes)
{
  tree def;

  if (gimple_code (stmt) == GIMPLE_ASSIGN)
    def = gimple_assign_lhs (stmt);
  else if (gimple_code (stmt) == GIMPLE_CALL)
    def = gimple_call_lhs (stmt);
  else if (gimple_code (stmt) == GIMPLE_PHI)
    def = gimple_phi_result (stmt);
  else
    return;


  build_cross_bb_scalars_def (scop, def, gimple_bb (stmt), writes);

  ssa_op_iter iter;
  use_operand_p use_p;
  FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
    {
      tree use = USE_FROM_PTR (use_p);
      build_cross_bb_scalars_use (scop, use, stmt, reads);
    }
}

/* Generates a polyhedral black box only if the bb contains interesting
   information.  */

static gimple_poly_bb_p
try_generate_gimple_bb (scop_p scop, basic_block bb)
{
  vec<data_reference_p> drs = vNULL;
  vec<tree> writes = vNULL;
  vec<scalar_use> reads = vNULL;

  sese_l region = scop->scop_info->region;
  loop_p nest = outermost_loop_in_sese (region, bb);

  loop_p loop = bb->loop_father;
  if (!loop_in_sese_p (loop, region))
    loop = nest;

  for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
       gsi_next (&gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      if (is_gimple_debug (stmt))
	continue;

      graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
      graphite_find_cross_bb_scalar_vars (scop, stmt, &reads, &writes);
    }

  for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
       gsi_next (&psi))
    if (!virtual_operand_p (gimple_phi_result (psi.phi ())))
      graphite_find_cross_bb_scalar_vars (scop, psi.phi (), &reads, &writes);

  if (drs.is_empty () && writes.is_empty () && reads.is_empty ())
    return NULL;

  return new_gimple_poly_bb (bb, drs, reads, writes);
}

/* Compute alias-sets for all data references in DRS.  */

static void
build_alias_set (scop_p scop)
{
  int num_vertices = scop->drs.length ();
  struct graph *g = new_graph (num_vertices);
  dr_info *dr1, *dr2;
  int i, j;
  int *all_vertices;

  struct loop *nest
    = find_common_loop (scop->scop_info->region.entry->dest->loop_father,
			scop->scop_info->region.exit->src->loop_father);

  FOR_EACH_VEC_ELT (scop->drs, i, dr1)
    for (j = i+1; scop->drs.iterate (j, &dr2); j++)
      if (dr_may_alias_p (dr1->dr, dr2->dr, nest))
	{
	  add_edge (g, i, j);
	  add_edge (g, j, i);
	}

  all_vertices = XNEWVEC (int, num_vertices);
  for (i = 0; i < num_vertices; i++)
    all_vertices[i] = i;

  graphds_dfs (g, all_vertices, num_vertices, NULL, true, NULL);
  free (all_vertices);

  for (i = 0; i < g->n_vertices; i++)
    scop->drs[i].alias_set = g->vertices[i].component + 1;

  free_graph (g);
}

/* Gather BBs and conditions for a SCOP.  */
class gather_bbs : public dom_walker
{
public:
  gather_bbs (cdi_direction, scop_p);

  virtual edge before_dom_children (basic_block);
  virtual void after_dom_children (basic_block);

private:
  auto_vec<gimple *, 3> conditions, cases;
  scop_p scop;
};
}
gather_bbs::gather_bbs (cdi_direction direction, scop_p scop)
  : dom_walker (direction), scop (scop)
{
}

/* Record in execution order the loops fully contained in the region.  */

static void
record_loop_in_sese (basic_block bb, sese_info_p region)
{
  loop_p father = bb->loop_father;
  if (loop_in_sese_p (father, region->region))
    {
      bool found = false;
      loop_p loop0;
      int j;
      FOR_EACH_VEC_ELT (region->loop_nest, j, loop0)
	if (father == loop0)
	  {
	    found = true;
	    break;
	  }
      if (!found)
	region->loop_nest.safe_push (father);
    }
}

/* Call-back for dom_walk executed before visiting the dominated
   blocks.  */

edge
gather_bbs::before_dom_children (basic_block bb)
{
  sese_info_p region = scop->scop_info;
  if (!bb_in_sese_p (bb, region->region))
    return NULL;

  record_loop_in_sese (bb, region);

  gcond *stmt = single_pred_cond_non_loop_exit (bb);

  if (stmt)
    {
      edge e = single_pred_edge (bb);

      conditions.safe_push (stmt);

      if (e->flags & EDGE_TRUE_VALUE)
	cases.safe_push (stmt);
      else
	cases.safe_push (NULL);
    }

  scop->scop_info->bbs.safe_push (bb);

  gimple_poly_bb_p gbb = try_generate_gimple_bb (scop, bb);
  if (!gbb)
    return NULL;

  GBB_CONDITIONS (gbb) = conditions.copy ();
  GBB_CONDITION_CASES (gbb) = cases.copy ();

  poly_bb_p pbb = new_poly_bb (scop, gbb);
  scop->pbbs.safe_push (pbb);

  int i;
  data_reference_p dr;
  FOR_EACH_VEC_ELT (gbb->data_refs, i, dr)
    {
      DEBUG_PRINT (dp << "Adding memory ";
		   if (dr->is_read)
		     dp << "read: ";
		   else
		     dp << "write: ";
		   print_generic_expr (dump_file, dr->ref, 0);
		   dp << "\nFrom stmt: ";
		   print_gimple_stmt (dump_file, dr->stmt, 0, 0));

      scop->drs.safe_push (dr_info (dr, pbb));
    }

  return NULL;
}

/* Call-back for dom_walk executed after visiting the dominated
   blocks.  */

void
gather_bbs::after_dom_children (basic_block bb)
{
  if (!bb_in_sese_p (bb, scop->scop_info->region))
    return;

  if (single_pred_cond_non_loop_exit (bb))
    {
      conditions.pop ();
      cases.pop ();
    }
}

/* Find Static Control Parts (SCoP) in the current function and pushes
   them to SCOPS.  */

void
build_scops (vec<scop_p> *scops)
{
  if (dump_file)
    dp.set_dump_file (dump_file);

  canonicalize_loop_closed_ssa_form ();

  scop_detection sb;
  sb.build_scop_depth (scop_detection::invalid_sese, current_loops->tree_root);

  /* Now create scops from the lightweight SESEs.  */
  vec<sese_l> scops_l = sb.get_scops ();
  int i;
  sese_l *s;
  FOR_EACH_VEC_ELT (scops_l, i, s)
    {
      scop_p scop = new_scop (s->entry, s->exit);

      /* Record all basic blocks and their conditions in REGION.  */
      gather_bbs (CDI_DOMINATORS, scop).walk (cfun->cfg->x_entry_block_ptr);

      build_alias_set (scop);

      /* Do not optimize a scop containing only PBBs that do not belong
	 to any loops.  */
      if (sb.nb_pbbs_in_loops (scop) == 0)
	{
	  DEBUG_PRINT (dp << "[scop-detection-fail] no data references.\n");
	  free_scop (scop);
	  continue;
	}

      unsigned max_arrays = PARAM_VALUE (PARAM_GRAPHITE_MAX_ARRAYS_PER_SCOP);
      if (scop->drs.length () >= max_arrays)
	{
	  DEBUG_PRINT (dp << "[scop-detection-fail] too many data references: "
		       << scop->drs.length ()
		       << " is larger than --param graphite-max-arrays-per-scop="
		       << max_arrays << ".\n");
	  free_scop (scop);
	  continue;
	}

      find_scop_parameters (scop);
      graphite_dim_t max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);

      if (scop_nb_params (scop) > max_dim)
	{
	  DEBUG_PRINT (dp << "[scop-detection-fail] too many parameters: "
			  << scop_nb_params (scop)
			  << " larger than --param graphite-max-nb-scop-params="
			  << max_dim << ".\n");
	  free_scop (scop);
	  continue;
	}

      scops->safe_push (scop);
    }

  DEBUG_PRINT (dp << "number of SCoPs: " << (scops ? scops->length () : 0););
}

#endif /* HAVE_isl */
