/* Translation of isl AST to Gimple.
   Copyright (C) 2014-2022 Free Software Foundation, Inc.
   Contributed by Roman Gareev <gareevroman@gmail.com>.

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 INCLUDE_ISL

#include "config.h"

#ifdef HAVE_isl

#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "cfghooks.h"
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "fold-const.h"
#include "gimple-fold.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "gimplify-me.h"
#include "tree-eh.h"
#include "tree-ssa-loop.h"
#include "tree-ssa-operands.h"
#include "tree-ssa-propagate.h"
#include "tree-pass.h"
#include "cfgloop.h"
#include "tree-data-ref.h"
#include "tree-ssa-loop-manip.h"
#include "tree-scalar-evolution.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "tree-into-ssa.h"
#include "ssa-iterators.h"
#include "tree-cfg.h"
#include "gimple-pretty-print.h"
#include "cfganal.h"
#include "value-prof.h"
#include "tree-ssa.h"
#include "tree-vectorizer.h"
#include "graphite.h"

struct ast_build_info
{
  ast_build_info()
    : is_parallelizable(false)
  { }
  bool is_parallelizable;
};

/* IVS_PARAMS maps isl's scattering and parameter identifiers
   to corresponding trees.  */

typedef hash_map<isl_id *, tree> ivs_params;

/* Free all memory allocated for isl's identifiers.  */

static void ivs_params_clear (ivs_params &ip)
{
  for (auto it = ip.begin (); it != ip.end (); ++it)
    isl_id_free ((*it).first);
}

/* Set the "separate" option for the schedule node.  */

static isl_schedule_node *
set_separate_option (__isl_take isl_schedule_node *node, void *user)
{
  if (user)
    return node;

  if (isl_schedule_node_get_type (node) != isl_schedule_node_band)
    return node;

  /* Set the "separate" option unless it is set earlier to another option.  */
  if (isl_schedule_node_band_member_get_ast_loop_type (node, 0)
      == isl_ast_loop_default)
    return isl_schedule_node_band_member_set_ast_loop_type
      (node, 0, isl_ast_loop_separate);

  return node;
}

/* Print SCHEDULE under an AST form on file F.  */

void
print_schedule_ast (FILE *f, __isl_keep isl_schedule *schedule, scop_p scop)
{
  isl_set *set = isl_set_params (isl_set_copy (scop->param_context));
  isl_ast_build *context = isl_ast_build_from_context (set);
  isl_ast_node *ast
    = isl_ast_build_node_from_schedule (context, isl_schedule_copy (schedule));
  isl_ast_build_free (context);
  print_isl_ast (f, ast);
  isl_ast_node_free (ast);
}

DEBUG_FUNCTION void
debug_schedule_ast (__isl_keep isl_schedule *s, scop_p scop)
{
  print_schedule_ast (stderr, s, scop);
}

enum phi_node_kind
{
  unknown_phi,
  loop_phi,
  close_phi,
  cond_phi
};

class translate_isl_ast_to_gimple
{
 public:
  translate_isl_ast_to_gimple (sese_info_p r);
  edge translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
			  edge next_e, ivs_params &ip);
  edge translate_isl_ast_node_for (loop_p context_loop,
				   __isl_keep isl_ast_node *node,
				   edge next_e, ivs_params &ip);
  edge translate_isl_ast_for_loop (loop_p context_loop,
				   __isl_keep isl_ast_node *node_for,
				   edge next_e,
				   tree type, tree lb, tree ub,
				   ivs_params &ip);
  edge translate_isl_ast_node_if (loop_p context_loop,
				  __isl_keep isl_ast_node *node,
				  edge next_e, ivs_params &ip);
  edge translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
				    edge next_e, ivs_params &ip);
  edge translate_isl_ast_node_block (loop_p context_loop,
				     __isl_keep isl_ast_node *node,
				     edge next_e, ivs_params &ip);
  tree unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
			 ivs_params &ip);
  tree binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
			  ivs_params &ip);
  tree ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
			   ivs_params &ip);
  tree nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
			ivs_params &ip);
  tree gcc_expression_from_isl_expression (tree type,
					   __isl_take isl_ast_expr *,
					   ivs_params &ip);
  tree gcc_expression_from_isl_ast_expr_id (tree type,
					    __isl_keep isl_ast_expr *expr_id,
					    ivs_params &ip);
  widest_int widest_int_from_isl_expr_int (__isl_keep isl_ast_expr *expr);
  tree gcc_expression_from_isl_expr_int (tree type,
					 __isl_take isl_ast_expr *expr);
  tree gcc_expression_from_isl_expr_op (tree type,
					__isl_take isl_ast_expr *expr,
					ivs_params &ip);
  struct loop *graphite_create_new_loop (edge entry_edge,
					 __isl_keep isl_ast_node *node_for,
					 loop_p outer, tree type,
					 tree lb, tree ub, ivs_params &ip);
  edge graphite_create_new_guard (edge entry_edge,
				  __isl_take isl_ast_expr *if_cond,
				  ivs_params &ip);
  void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
			 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
			 sese_l &region);
  void add_parameters_to_ivs_params (scop_p scop, ivs_params &ip);
  __isl_give isl_ast_build *generate_isl_context (scop_p scop);

  __isl_give isl_ast_node * scop_to_isl_ast (scop_p scop);

  tree get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
			     vec<tree> iv_map);
  void graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
				       vec<tree> iv_map);
  edge copy_bb_and_scalar_dependences (basic_block bb, edge next_e,
				       vec<tree> iv_map);
  void set_rename (tree old_name, tree expr);
  void gsi_insert_earliest (gimple_seq seq);
  bool codegen_error_p () const { return codegen_error; }

  void set_codegen_error ()
  {
    codegen_error = true;
    gcc_assert (! flag_checking
		|| param_graphite_allow_codegen_errors);
  }

  bool is_constant (tree op) const
  {
    return TREE_CODE (op) == INTEGER_CST
      || TREE_CODE (op) == REAL_CST
      || TREE_CODE (op) == COMPLEX_CST
      || TREE_CODE (op) == VECTOR_CST;
  }

private:
  /* The region to be translated.  */
  sese_info_p region;

  /* This flag is set when an error occurred during the translation of isl AST
     to Gimple.  */
  bool codegen_error;

  /* A vector of all the edges at if_condition merge points.  */
  auto_vec<edge, 2> merge_points;

  tree graphite_expr_type;
};

translate_isl_ast_to_gimple::translate_isl_ast_to_gimple (sese_info_p r)
  : region (r), codegen_error (false)
{
  /* We always try to use signed 128 bit types, but fall back to smaller types
     in case a platform does not provide types of these sizes. In the future we
     should use isl to derive the optimal type for each subexpression.  */
  int max_mode_int_precision
    = GET_MODE_PRECISION (int_mode_for_size (MAX_FIXED_MODE_SIZE, 0).require ());
  int graphite_expr_type_precision
    = 128 <= max_mode_int_precision ?  128 : max_mode_int_precision;
  graphite_expr_type
    = build_nonstandard_integer_type (graphite_expr_type_precision, 0);
}

/* Return the tree variable that corresponds to the given isl ast identifier
   expression (an isl_ast_expr of type isl_ast_expr_id).

   FIXME: We should replace blind conversion of id's type with derivation
   of the optimal type when we get the corresponding isl support.  Blindly
   converting type sizes may be problematic when we switch to smaller
   types.  */

tree translate_isl_ast_to_gimple::
gcc_expression_from_isl_ast_expr_id (tree type,
				     __isl_take isl_ast_expr *expr_id,
				     ivs_params &ip)
{
  gcc_assert (isl_ast_expr_get_type (expr_id) == isl_ast_expr_id);
  isl_id *tmp_isl_id = isl_ast_expr_get_id (expr_id);
  tree *tp = ip.get (tmp_isl_id);
  isl_id_free (tmp_isl_id);
  gcc_assert (tp && "Could not map isl_id to tree expression");
  isl_ast_expr_free (expr_id);
  tree t = *tp;
  if (useless_type_conversion_p (type, TREE_TYPE (t)))
    return t;
  if (POINTER_TYPE_P (TREE_TYPE (t))
      && !POINTER_TYPE_P (type) && !ptrofftype_p (type))
    t = fold_convert (sizetype, t);
  return fold_convert (type, t);
}

/* Converts an isl_ast_expr_int expression E to a widest_int.
   Raises a code generation error when the constant doesn't fit.  */

widest_int translate_isl_ast_to_gimple::
widest_int_from_isl_expr_int (__isl_keep isl_ast_expr *expr)
{
  gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_int);
  isl_val *val = isl_ast_expr_get_val (expr);
  size_t n = isl_val_n_abs_num_chunks (val, sizeof (HOST_WIDE_INT));
  HOST_WIDE_INT *chunks = XALLOCAVEC (HOST_WIDE_INT, n);
  if (n > WIDE_INT_MAX_ELTS
      || isl_val_get_abs_num_chunks (val, sizeof (HOST_WIDE_INT), chunks) == -1)
    {
      isl_val_free (val);
      set_codegen_error ();
      return 0;
    }
  widest_int wi = widest_int::from_array (chunks, n, true);
  if (isl_val_is_neg (val))
    wi = -wi;
  isl_val_free (val);
  return wi;
}

/* Converts an isl_ast_expr_int expression E to a GCC expression tree of
   type TYPE.  Raises a code generation error when the constant doesn't fit.  */

tree translate_isl_ast_to_gimple::
gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
{
  widest_int wi = widest_int_from_isl_expr_int (expr);
  isl_ast_expr_free (expr);
  if (codegen_error_p ())
    return NULL_TREE;
  if (wi::min_precision (wi, TYPE_SIGN (type)) > TYPE_PRECISION (type))
    {
      set_codegen_error ();
      return NULL_TREE;
    }
  return wide_int_to_tree (type, wi);
}

/* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
   type TYPE.  */

tree translate_isl_ast_to_gimple::
binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
{
  enum isl_ast_op_type expr_type = isl_ast_expr_get_op_type (expr);
  isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
  tree tree_lhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
  arg_expr = isl_ast_expr_get_op_arg (expr, 1);
  isl_ast_expr_free (expr);

  /* From our constraint generation we may get modulo operations that
     we cannot represent explicitely but that are no-ops for TYPE.
     Elide those.  */
  if ((expr_type == isl_ast_op_pdiv_r
       || expr_type == isl_ast_op_zdiv_r
       || expr_type == isl_ast_op_add)
      && isl_ast_expr_get_type (arg_expr) == isl_ast_expr_int
      && (wi::exact_log2 (widest_int_from_isl_expr_int (arg_expr))
	  >= TYPE_PRECISION (type)))
    {
      isl_ast_expr_free (arg_expr);
      return tree_lhs_expr;
    }

  tree tree_rhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
  if (codegen_error_p ())
    return NULL_TREE;

  switch (expr_type)
    {
    case isl_ast_op_add:
      return fold_build2 (PLUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_sub:
      return fold_build2 (MINUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_mul:
      return fold_build2 (MULT_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_div:
      return fold_build2 (EXACT_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_pdiv_q:
      return fold_build2 (TRUNC_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_zdiv_r:
    case isl_ast_op_pdiv_r:
      return fold_build2 (TRUNC_MOD_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_fdiv_q:
      return fold_build2 (FLOOR_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_and:
      return fold_build2 (TRUTH_ANDIF_EXPR, type,
			  tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_or:
      return fold_build2 (TRUTH_ORIF_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_eq:
      return fold_build2 (EQ_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_le:
      return fold_build2 (LE_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_lt:
      return fold_build2 (LT_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_ge:
      return fold_build2 (GE_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    case isl_ast_op_gt:
      return fold_build2 (GT_EXPR, type, tree_lhs_expr, tree_rhs_expr);

    default:
      gcc_unreachable ();
    }
}

/* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
   type TYPE.  */

tree translate_isl_ast_to_gimple::
ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
{
  enum isl_ast_op_type t = isl_ast_expr_get_op_type (expr);
  gcc_assert (t == isl_ast_op_cond || t == isl_ast_op_select);
  isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
  tree a = gcc_expression_from_isl_expression (type, arg_expr, ip);
  arg_expr = isl_ast_expr_get_op_arg (expr, 1);
  tree b = gcc_expression_from_isl_expression (type, arg_expr, ip);
  arg_expr = isl_ast_expr_get_op_arg (expr, 2);
  tree c = gcc_expression_from_isl_expression (type, arg_expr, ip);
  isl_ast_expr_free (expr);

  if (codegen_error_p ())
    return NULL_TREE;

  return fold_build3 (COND_EXPR, type, a,
		      rewrite_to_non_trapping_overflow (b),
		      rewrite_to_non_trapping_overflow (c));
}

/* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
   type TYPE.  */

tree translate_isl_ast_to_gimple::
unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
{
  gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
  isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
  tree tree_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
  isl_ast_expr_free (expr);
  return codegen_error_p () ? NULL_TREE
    : fold_build1 (NEGATE_EXPR, type, tree_expr);
}

/* Converts an isl_ast_expr_op expression E with unknown number of arguments
   to a GCC expression tree of type TYPE.  */

tree translate_isl_ast_to_gimple::
nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
{
  enum tree_code op_code;
  switch (isl_ast_expr_get_op_type (expr))
    {
    case isl_ast_op_max:
      op_code = MAX_EXPR;
      break;

    case isl_ast_op_min:
      op_code = MIN_EXPR;
      break;

    default:
      gcc_unreachable ();    
    }
  isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
  tree res = gcc_expression_from_isl_expression (type, arg_expr, ip);

  if (codegen_error_p ())
    {
      isl_ast_expr_free (expr);
      return NULL_TREE;
    }

  int i;
  for (i = 1; i < isl_ast_expr_get_op_n_arg (expr); i++)
    {
      arg_expr = isl_ast_expr_get_op_arg (expr, i);
      tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);

      if (codegen_error_p ())
	{
	  isl_ast_expr_free (expr);
	  return NULL_TREE;
	}

      res = fold_build2 (op_code, type, res, t);
    }
  isl_ast_expr_free (expr);
  return res;
}

/* Converts an isl_ast_expr_op expression E to a GCC expression tree of
   type TYPE.  */

tree translate_isl_ast_to_gimple::
gcc_expression_from_isl_expr_op (tree type, __isl_take isl_ast_expr *expr,
				 ivs_params &ip)
{
  if (codegen_error_p ())
    {
      isl_ast_expr_free (expr);
      return NULL_TREE;
    }

  gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_op);
  switch (isl_ast_expr_get_op_type (expr))
    {
    /* These isl ast expressions are not supported yet.  */
    case isl_ast_op_error:
    case isl_ast_op_call:
    case isl_ast_op_and_then:
    case isl_ast_op_or_else:
      gcc_unreachable ();

    case isl_ast_op_max:
    case isl_ast_op_min:
      return nary_op_to_tree (type, expr, ip);

    case isl_ast_op_add:
    case isl_ast_op_sub:
    case isl_ast_op_mul:
    case isl_ast_op_div:
    case isl_ast_op_pdiv_q:
    case isl_ast_op_pdiv_r:
    case isl_ast_op_fdiv_q:
    case isl_ast_op_zdiv_r:
    case isl_ast_op_and:
    case isl_ast_op_or:
    case isl_ast_op_eq:
    case isl_ast_op_le:
    case isl_ast_op_lt:
    case isl_ast_op_ge:
    case isl_ast_op_gt:
      return binary_op_to_tree (type, expr, ip);

    case isl_ast_op_minus:
      return unary_op_to_tree (type, expr, ip);

    case isl_ast_op_cond:
    case isl_ast_op_select:
      return ternary_op_to_tree (type, expr, ip);

    default:
      gcc_unreachable ();
    }
}

/* Converts an isl AST expression E back to a GCC expression tree of
   type TYPE.  */

tree translate_isl_ast_to_gimple::
gcc_expression_from_isl_expression (tree type, __isl_take isl_ast_expr *expr,
				    ivs_params &ip)
{
  if (codegen_error_p ())
    {
      isl_ast_expr_free (expr);
      return NULL_TREE;
    }

  switch (isl_ast_expr_get_type (expr))
    {
    case isl_ast_expr_id:
      return gcc_expression_from_isl_ast_expr_id (type, expr, ip);

    case isl_ast_expr_int:
      return gcc_expression_from_isl_expr_int (type, expr);

    case isl_ast_expr_op:
      return gcc_expression_from_isl_expr_op (type, expr, ip);

    default:
      gcc_unreachable ();
    }
}

/* Creates a new LOOP corresponding to isl_ast_node_for.  Inserts an
   induction variable for the new LOOP.  New LOOP is attached to CFG
   starting at ENTRY_EDGE.  LOOP is inserted into the loop tree and
   becomes the child loop of the OUTER_LOOP.  NEWIVS_INDEX binds
   isl's scattering name to the induction variable created for the
   loop of STMT.  The new induction variable is inserted in the NEWIVS
   vector and is of type TYPE.  */

struct loop *translate_isl_ast_to_gimple::
graphite_create_new_loop (edge entry_edge, __isl_keep isl_ast_node *node_for,
			  loop_p outer, tree type, tree lb, tree ub,
			  ivs_params &ip)
{
  isl_ast_expr *for_inc = isl_ast_node_for_get_inc (node_for);
  tree stride = gcc_expression_from_isl_expression (type, for_inc, ip);

  /* To fail code generation, we generate wrong code until we discard it.  */
  if (codegen_error_p ())
    stride = integer_zero_node;

  tree ivvar = create_tmp_var (type, "graphite_IV");
  tree iv, iv_after_increment;
  loop_p loop = create_empty_loop_on_edge
    (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
     outer ? outer : entry_edge->src->loop_father);

  isl_ast_expr *for_iterator = isl_ast_node_for_get_iterator (node_for);
  isl_id *id = isl_ast_expr_get_id (for_iterator);
  bool existed_p = ip.put (id, iv);
  if (existed_p)
    isl_id_free (id);
  isl_ast_expr_free (for_iterator);
  return loop;
}

/* Create the loop for a isl_ast_node_for.

   - NEXT_E is the edge where new generated code should be attached.  */

edge translate_isl_ast_to_gimple::
translate_isl_ast_for_loop (loop_p context_loop,
			    __isl_keep isl_ast_node *node_for, edge next_e,
			    tree type, tree lb, tree ub,
			    ivs_params &ip)
{
  gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
  struct loop *loop = graphite_create_new_loop (next_e, node_for, context_loop,
						type, lb, ub, ip);
  edge last_e = single_exit (loop);
  edge to_body = single_succ_edge (loop->header);
  basic_block after = to_body->dest;

  /* Translate the body of the loop.  */
  isl_ast_node *for_body = isl_ast_node_for_get_body (node_for);
  next_e = translate_isl_ast (loop, for_body, to_body, ip);
  isl_ast_node_free (for_body);

  /* Early return if we failed to translate loop body.  */
  if (!next_e || codegen_error_p ())
    return NULL;

  if (next_e->dest != after)
    redirect_edge_succ_nodup (next_e, after);
  set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);

  if (flag_loop_parallelize_all)
    {
      isl_id *id = isl_ast_node_get_annotation (node_for);
      gcc_assert (id);
      ast_build_info *for_info = (ast_build_info *) isl_id_get_user (id);
      loop->can_be_parallel = for_info->is_parallelizable;
      free (for_info);
      isl_id_free (id);
    }

  return last_e;
}

/* We use this function to get the upper bound because of the form,
   which is used by isl to represent loops:

   for (iterator = init; cond; iterator += inc)

   {

   ...

   }

   The loop condition is an arbitrary expression, which contains the
   current loop iterator.

   (e.g. iterator + 3 < B && C > iterator + A)

   We have to know the upper bound of the iterator to generate a loop
   in Gimple form. It can be obtained from the special representation
   of the loop condition, which is generated by isl,
   if the ast_build_atomic_upper_bound option is set. In this case,
   isl generates a loop condition that consists of the current loop
   iterator, + an operator (< or <=) and an expression not involving
   the iterator, which is processed and returned by this function.

   (e.g iterator <= upper-bound-expression-without-iterator)  */

static __isl_give isl_ast_expr *
get_upper_bound (__isl_keep isl_ast_node *node_for)
{
  gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
  isl_ast_expr *for_cond = isl_ast_node_for_get_cond (node_for);
  gcc_assert (isl_ast_expr_get_type (for_cond) == isl_ast_expr_op);
  isl_ast_expr *res;
  switch (isl_ast_expr_get_op_type (for_cond))
    {
    case isl_ast_op_le:
      res = isl_ast_expr_get_op_arg (for_cond, 1);
      break;

    case isl_ast_op_lt:
      {
	/* (iterator < ub) => (iterator <= ub - 1).  */
        isl_val *one =
          isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
        isl_ast_expr *ub = isl_ast_expr_get_op_arg (for_cond, 1);
        res = isl_ast_expr_sub (ub, isl_ast_expr_from_val (one));
        break;
      }

    default:
      gcc_unreachable ();
    }
  isl_ast_expr_free (for_cond);
  return res;
}

/* Translates an isl_ast_node_for to Gimple. */

edge translate_isl_ast_to_gimple::
translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
			    edge next_e, ivs_params &ip)
{
  gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
  tree type = graphite_expr_type;

  isl_ast_expr *for_init = isl_ast_node_for_get_init (node);
  tree lb = gcc_expression_from_isl_expression (type, for_init, ip);
  /* To fail code generation, we generate wrong code until we discard it.  */
  if (codegen_error_p ())
    lb = integer_zero_node;

  isl_ast_expr *upper_bound = get_upper_bound (node);
  tree ub = gcc_expression_from_isl_expression (type, upper_bound, ip);
  /* To fail code generation, we generate wrong code until we discard it.  */
  if (codegen_error_p ())
    ub = integer_zero_node;

  edge last_e = single_succ_edge (split_edge (next_e));

  /* Compensate for the fact that we emit a do { } while loop from
     a for ISL AST.
     ???  We often miss constraints on niter because the SESE region
     doesn't cover loop header copies.  Ideally we'd add constraints
     for all relevant dominating conditions.  */
  if (TREE_CODE (lb) == INTEGER_CST && TREE_CODE (ub) == INTEGER_CST
      && tree_int_cst_compare (lb, ub) <= 0)
    ;
  else
    {
      tree one = build_one_cst (POINTER_TYPE_P (type) ? sizetype : type);
      /* Adding +1 and using LT_EXPR helps with loop latches that have a
	 loop iteration count of "PARAMETER - 1".  For PARAMETER == 0 this
	 becomes 2^k-1 due to integer overflow, and the condition lb <= ub
	 is true, even if we do not want this.  However lb < ub + 1 is false,
	 as expected.  */
      tree ub_one = fold_build2 (POINTER_TYPE_P (type)
				 ? POINTER_PLUS_EXPR : PLUS_EXPR,
				 type, unshare_expr (ub), one);
      create_empty_if_region_on_edge (next_e,
				      fold_build2 (LT_EXPR, boolean_type_node,
						   unshare_expr (lb), ub_one));
      next_e = get_true_edge_from_guard_bb (next_e->dest);
    }

  translate_isl_ast_for_loop (context_loop, node, next_e,
			      type, lb, ub, ip);
  return last_e;
}

/* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
   variables of the loops around GBB in SESE.
 
   FIXME: Instead of using a vec<tree> that maps each loop id to a possible
   chrec, we could consider using a map<int, tree> that maps loop ids to the
   corresponding tree expressions.  */

void translate_isl_ast_to_gimple::
build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
		  __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
		  sese_l &region)
{
  gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
	      isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
  int i;
  isl_ast_expr *arg_expr;
  for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
    {
      arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
      tree type = graphite_expr_type;
      tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);

      /* To fail code generation, we generate wrong code until we discard it.  */
      if (codegen_error_p ())
	t = integer_zero_node;

      loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
      iv_map[old_loop->num] = t;
    }
}

/* Translates an isl_ast_node_user to Gimple.

   FIXME: We should remove iv_map.create (loop->num + 1), if it is possible.  */

edge translate_isl_ast_to_gimple::
translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
			     edge next_e, ivs_params &ip)
{
  gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);

  isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
  isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
  gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);

  isl_id *name_id = isl_ast_expr_get_id (name_expr);
  poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
  gcc_assert (pbb);

  gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);

  isl_ast_expr_free (name_expr);
  isl_id_free (name_id);

  gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
	      "The entry block should not even appear within a scop");

  const int nb_loops = number_of_loops (cfun);
  vec<tree> iv_map;
  iv_map.create (nb_loops);
  iv_map.safe_grow_cleared (nb_loops, true);

  build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
  isl_ast_expr_free (user_expr);

  basic_block old_bb = GBB_BB (gbb);
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file,
	       "[codegen] copying from bb_%d on edge (bb_%d, bb_%d)\n",
	       old_bb->index, next_e->src->index, next_e->dest->index);
      print_loops_bb (dump_file, GBB_BB (gbb), 0, 3);
    }

  next_e = copy_bb_and_scalar_dependences (old_bb, next_e, iv_map);

  iv_map.release ();

  if (codegen_error_p ())
    return NULL;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "[codegen] (after copy) new basic block\n");
      print_loops_bb (dump_file, next_e->src, 0, 3);
    }

  return next_e;
}

/* Translates an isl_ast_node_block to Gimple. */

edge translate_isl_ast_to_gimple::
translate_isl_ast_node_block (loop_p context_loop,
			      __isl_keep isl_ast_node *node,
			      edge next_e, ivs_params &ip)
{
  gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
  isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
  int i;
  for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
    {
      isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
      next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
      isl_ast_node_free (tmp_node);
    }
  isl_ast_node_list_free (node_list);
  return next_e;
}
 
/* Creates a new if region corresponding to isl's cond.  */

edge translate_isl_ast_to_gimple::
graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
			   ivs_params &ip)
{
  tree type = graphite_expr_type;
  tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);

  /* To fail code generation, we generate wrong code until we discard it.  */
  if (codegen_error_p ())
    cond_expr = integer_zero_node;

  edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
  return exit_edge;
}

/* Translates an isl_ast_node_if to Gimple.  */

edge translate_isl_ast_to_gimple::
translate_isl_ast_node_if (loop_p context_loop,
			   __isl_keep isl_ast_node *node,
			   edge next_e, ivs_params &ip)
{
  gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
  isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
  edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
  edge true_e = get_true_edge_from_guard_bb (next_e->dest);
  merge_points.safe_push (last_e);

  isl_ast_node *then_node = isl_ast_node_if_get_then (node);
  translate_isl_ast (context_loop, then_node, true_e, ip);
  isl_ast_node_free (then_node);

  edge false_e = get_false_edge_from_guard_bb (next_e->dest);
  isl_ast_node *else_node = isl_ast_node_if_get_else (node);
  if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
    translate_isl_ast (context_loop, else_node, false_e, ip);

  isl_ast_node_free (else_node);
  return last_e;
}

/* Translates an isl AST node NODE to GCC representation in the
   context of a SESE.  */

edge translate_isl_ast_to_gimple::
translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
		   edge next_e, ivs_params &ip)
{
  if (codegen_error_p ())
    return NULL;

  switch (isl_ast_node_get_type (node))
    {
    case isl_ast_node_error:
      gcc_unreachable ();

    case isl_ast_node_for:
      return translate_isl_ast_node_for (context_loop, node,
					 next_e, ip);

    case isl_ast_node_if:
      return translate_isl_ast_node_if (context_loop, node,
					next_e, ip);

    case isl_ast_node_user:
      return translate_isl_ast_node_user (node, next_e, ip);

    case isl_ast_node_block:
      return translate_isl_ast_node_block (context_loop, node,
					   next_e, ip);

    case isl_ast_node_mark:
      {
	isl_ast_node *n = isl_ast_node_mark_get_node (node);
	edge e = translate_isl_ast (context_loop, n, next_e, ip);
	isl_ast_node_free (n);
	return e;
      }

    default:
      gcc_unreachable ();
    }
}

/* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
   When OLD_NAME and EXPR are the same we assert.  */

void translate_isl_ast_to_gimple::
set_rename (tree old_name, tree expr)
{
  if (dump_file)
    {
      fprintf (dump_file, "[codegen] setting rename: old_name = ");
      print_generic_expr (dump_file, old_name);
      fprintf (dump_file, ", new decl = ");
      print_generic_expr (dump_file, expr);
      fprintf (dump_file, "\n");
    }
  bool res = region->rename_map->put (old_name, expr);
  gcc_assert (! res);
}

/* Return an iterator to the instructions comes last in the execution order.
   Either GSI1 and GSI2 should belong to the same basic block or one of their
   respective basic blocks should dominate the other.  */

gimple_stmt_iterator
later_of_the_two (gimple_stmt_iterator gsi1, gimple_stmt_iterator gsi2)
{
  basic_block bb1 = gsi_bb (gsi1);
  basic_block bb2 = gsi_bb (gsi2);

  /* Find the iterator which is the latest.  */
  if (bb1 == bb2)
    {
      gimple *stmt1 = gsi_stmt (gsi1);
      gimple *stmt2 = gsi_stmt (gsi2);

      if (stmt1 != NULL && stmt2 != NULL)
	{
	  bool is_phi1 = gimple_code (stmt1) == GIMPLE_PHI;
	  bool is_phi2 = gimple_code (stmt2) == GIMPLE_PHI;

	  if (is_phi1 != is_phi2)
	    return is_phi1 ? gsi2 : gsi1;
	}

      /* For empty basic blocks gsis point to the end of the sequence.  Since
	 there is no operator== defined for gimple_stmt_iterator and for gsis
	 not pointing to a valid statement gsi_next would assert.  */
      gimple_stmt_iterator gsi = gsi1;
      do {
	if (gsi_stmt (gsi) == gsi_stmt (gsi2))
	  return gsi2;
	gsi_next (&gsi);
      } while (!gsi_end_p (gsi));

      return gsi1;
    }

  /* Find the basic block closest to the basic block which defines stmt.  */
  if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
    return gsi1;

  gcc_assert (dominated_by_p (CDI_DOMINATORS, bb2, bb1));
  return gsi2;
}

/* Insert each statement from SEQ at its earliest insertion p.  */

void translate_isl_ast_to_gimple::
gsi_insert_earliest (gimple_seq seq)
{
  update_modified_stmts (seq);
  sese_l &codegen_region = region->if_region->true_region->region;
  basic_block begin_bb = get_entry_bb (codegen_region);

  /* Inserting the gimple statements in a vector because gimple_seq behave
     in strage ways when inserting the stmts from it into different basic
     blocks one at a time.  */
  auto_vec<gimple *, 3> stmts;
  for (gimple_stmt_iterator gsi = gsi_start (seq); !gsi_end_p (gsi);
       gsi_next (&gsi))
    stmts.safe_push (gsi_stmt (gsi));

  int i;
  gimple *use_stmt;
  FOR_EACH_VEC_ELT (stmts, i, use_stmt)
    {
      gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
      gimple_stmt_iterator gsi_def_stmt = gsi_start_nondebug_bb (begin_bb);

      use_operand_p use_p;
      ssa_op_iter op_iter;
      FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, op_iter, SSA_OP_USE)
	{
	  /* Iterator to the current def of use_p.  For function parameters or
	     anything where def is not found, insert at the beginning of the
	     generated region.  */
	  gimple_stmt_iterator gsi_stmt = gsi_def_stmt;

	  tree op = USE_FROM_PTR (use_p);
	  gimple *stmt = SSA_NAME_DEF_STMT (op);
	  if (stmt && (gimple_code (stmt) != GIMPLE_NOP))
	    gsi_stmt = gsi_for_stmt (stmt);

	  /* For region parameters, insert at the beginning of the generated
	     region.  */
	  if (!bb_in_sese_p (gsi_bb (gsi_stmt), codegen_region))
	    gsi_stmt = gsi_def_stmt;

	  gsi_def_stmt = later_of_the_two (gsi_stmt, gsi_def_stmt);
	}

      if (!gsi_stmt (gsi_def_stmt))
	{
	  gimple_stmt_iterator gsi = gsi_after_labels (gsi_bb (gsi_def_stmt));
	  gsi_insert_before (&gsi, use_stmt, GSI_NEW_STMT);
	}
      else if (gimple_code (gsi_stmt (gsi_def_stmt)) == GIMPLE_PHI)
	{
	  gimple_stmt_iterator bsi
	    = gsi_start_nondebug_bb (gsi_bb (gsi_def_stmt));
	  /* Insert right after the PHI statements.  */
	  gsi_insert_before (&bsi, use_stmt, GSI_NEW_STMT);
	}
      else
	gsi_insert_after (&gsi_def_stmt, use_stmt, GSI_NEW_STMT);

      if (dump_file)
	{
	  fprintf (dump_file, "[codegen] inserting statement in BB %d: ",
		   gimple_bb (use_stmt)->index);
	  print_gimple_stmt (dump_file, use_stmt, 0, TDF_VOPS | TDF_MEMSYMS);
	}
    }
}

/* For ops which are scev_analyzeable, we can regenerate a new name from its
   scalar evolution around LOOP.  */

tree translate_isl_ast_to_gimple::
get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
		      vec<tree> iv_map)
{
  tree scev = cached_scalar_evolution_in_region (region->region,
						 loop, old_name);

  /* At this point we should know the exact scev for each
     scalar SSA_NAME used in the scop: all the other scalar
     SSA_NAMEs should have been translated out of SSA using
     arrays with one element.  */
  tree new_expr;
  if (chrec_contains_undetermined (scev))
    {
      set_codegen_error ();
      return build_zero_cst (TREE_TYPE (old_name));
    }

  new_expr = chrec_apply_map (scev, iv_map);

  /* The apply should produce an expression tree containing
     the uses of the new induction variables.  We should be
     able to use new_expr instead of the old_name in the newly
     generated loop nest.  */
  if (chrec_contains_undetermined (new_expr)
      || tree_contains_chrecs (new_expr, NULL))
    {
      set_codegen_error ();
      return build_zero_cst (TREE_TYPE (old_name));
    }

  /* Replace the old_name with the new_expr.  */
  return force_gimple_operand (unshare_expr (new_expr), stmts,
			       true, NULL_TREE);
}


/* Return true if STMT should be copied from region to the new code-generated
   region.  LABELs, CONDITIONS, induction-variables and region parameters need
   not be copied.  */

static bool
should_copy_to_new_region (gimple *stmt, sese_info_p region)
{
  /* Do not copy labels or conditions.  */
  if (gimple_code (stmt) == GIMPLE_LABEL
      || gimple_code (stmt) == GIMPLE_COND)
    return false;

  tree lhs;
  /* Do not copy induction variables.  */
  if (is_gimple_assign (stmt)
      && (lhs = gimple_assign_lhs (stmt))
      && TREE_CODE (lhs) == SSA_NAME
      && scev_analyzable_p (lhs, region->region)
      /* But to code-generate liveouts - liveout PHI generation is
         in generic sese.cc code that cannot do code generation.  */
      && ! bitmap_bit_p (region->liveout, SSA_NAME_VERSION (lhs)))
    return false;

  return true;
}

/* Duplicates the statements of basic block BB into basic block NEW_BB
   and compute the new induction variables according to the IV_MAP.  */

void translate_isl_ast_to_gimple::
graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
				vec<tree> iv_map)
{
  /* Iterator poining to the place where new statement (s) will be inserted.  */
  gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);

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

      /* Create a new copy of STMT and duplicate STMT's virtual
	 operands.  */
      gimple *copy = gimple_copy (stmt);

      /* Rather than not copying debug stmts we reset them.
         ???  Where we can rewrite uses without inserting new
	 stmts we could simply do that.  */
      if (is_gimple_debug (copy))
	{
	  if (gimple_debug_bind_p (copy))
	    gimple_debug_bind_reset_value (copy);
	  else if (gimple_debug_source_bind_p (copy)
		   || gimple_debug_nonbind_marker_p (copy))
	    ;
	  else
	    gcc_unreachable ();
	}

      maybe_duplicate_eh_stmt (copy, stmt);
      gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);

      /* Crete new names for each def in the copied stmt.  */
      def_operand_p def_p;
      ssa_op_iter op_iter;
      FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
	{
	  tree old_name = DEF_FROM_PTR (def_p);
	  create_new_def_for (old_name, copy, def_p);
	}

      gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
      if (dump_file)
	{
	  fprintf (dump_file, "[codegen] inserting statement: ");
	  print_gimple_stmt (dump_file, copy, 0);
	}

      /* For each SCEV analyzable SSA_NAME, rename their usage.  */
      ssa_op_iter iter;
      use_operand_p use_p;
      if (!is_gimple_debug (copy))
	{
	  bool changed = false;
	  FOR_EACH_SSA_USE_OPERAND (use_p, copy, iter, SSA_OP_USE)
	    {
	      tree old_name = USE_FROM_PTR (use_p);

	      if (TREE_CODE (old_name) != SSA_NAME
		  || SSA_NAME_IS_DEFAULT_DEF (old_name)
		  || ! scev_analyzable_p (old_name, region->region))
		continue;

	      gimple_seq stmts = NULL;
	      tree new_name = get_rename_from_scev (old_name, &stmts,
						    bb->loop_father, iv_map);
	      if (! codegen_error_p ())
		gsi_insert_earliest (stmts);
	      replace_exp (use_p, new_name);
	      changed = true;
	    }
	  if (changed)
	    fold_stmt_inplace (&gsi_tgt);
	}

      update_stmt (copy);
    }
}


/* Copies BB and includes in the copied BB all the statements that can
   be reached following the use-def chains from the memory accesses,
   and returns the next edge following this new block.  */

edge translate_isl_ast_to_gimple::
copy_bb_and_scalar_dependences (basic_block bb, edge next_e, vec<tree> iv_map)
{
  basic_block new_bb = split_edge (next_e);
  gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);
  for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
       gsi_next (&psi))
    {
      gphi *phi = psi.phi ();
      tree res = gimple_phi_result (phi);
      if (virtual_operand_p (res)
	  || scev_analyzable_p (res, region->region))
	continue;

      tree new_phi_def;
      tree *rename = region->rename_map->get (res);
      if (! rename)
	{
	  new_phi_def = create_tmp_reg (TREE_TYPE (res));
	  set_rename (res, new_phi_def);
	}
      else
	new_phi_def = *rename;

      gassign *ass = gimple_build_assign (NULL_TREE, new_phi_def);
      create_new_def_for (res, ass, NULL);
      gsi_insert_after (&gsi_tgt, ass, GSI_NEW_STMT);
    }

  graphite_copy_stmts_from_block (bb, new_bb, iv_map);

  /* Insert out-of SSA copies on the original BB outgoing edges.  */
  gsi_tgt = gsi_last_bb (new_bb);
  basic_block bb_for_succs = bb;
  if (bb_for_succs == bb_for_succs->loop_father->latch
      && bb_in_sese_p (bb_for_succs, region->region)
      && sese_trivially_empty_bb_p (bb_for_succs))
    bb_for_succs = NULL;
  while (bb_for_succs)
    {
      basic_block latch = NULL;
      edge_iterator ei;
      edge e;
      FOR_EACH_EDGE (e, ei, bb_for_succs->succs)
	{
	  for (gphi_iterator psi = gsi_start_phis (e->dest); !gsi_end_p (psi);
	       gsi_next (&psi))
	    {
	      gphi *phi = psi.phi ();
	      tree res = gimple_phi_result (phi);
	      if (virtual_operand_p (res)
		  || scev_analyzable_p (res, region->region))
		continue;

	      tree new_phi_def;
	      tree *rename = region->rename_map->get (res);
	      if (! rename)
		{
		  new_phi_def = create_tmp_reg (TREE_TYPE (res));
		  set_rename (res, new_phi_def);
		}
	      else
		new_phi_def = *rename;

	      tree arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
	      if (TREE_CODE (arg) == SSA_NAME
		  && scev_analyzable_p (arg, region->region))
		{
		  gimple_seq stmts = NULL;
		  tree new_name = get_rename_from_scev (arg, &stmts,
							bb->loop_father,
							iv_map);
		  if (! codegen_error_p ())
		    gsi_insert_earliest (stmts);
		  arg = new_name;
		}
	      gassign *ass = gimple_build_assign (new_phi_def, arg);
	      gsi_insert_after (&gsi_tgt, ass, GSI_NEW_STMT);
	    }
	  if (e->dest == bb_for_succs->loop_father->latch
	      && bb_in_sese_p (e->dest, region->region)
	      && sese_trivially_empty_bb_p (e->dest))
	    latch = e->dest;
	}
      bb_for_succs = latch;
    }

  return single_succ_edge (new_bb);
}

/* Add isl's parameter identifiers and corresponding trees to ivs_params.  */

void translate_isl_ast_to_gimple::
add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
{
  sese_info_p region = scop->scop_info;
  unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
  gcc_assert (nb_parameters == sese_nb_params (region));
  unsigned i;
  tree param;
  FOR_EACH_VEC_ELT (region->params, i, param)
    {
      isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
					   isl_dim_param, i);
      bool existed_p = ip.put (tmp_id, param);
      gcc_assert (!existed_p);
    }
}


/* Generates a build, which specifies the constraints on the parameters.  */

__isl_give isl_ast_build *translate_isl_ast_to_gimple::
generate_isl_context (scop_p scop)
{
  isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
  return isl_ast_build_from_context (context_isl);
}

/* This method is executed before the construction of a for node.  */
__isl_give isl_id *
ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
{
  isl_union_map *dependences = (isl_union_map *) user;
  ast_build_info *for_info = XNEW (struct ast_build_info);
  isl_union_map *schedule = isl_ast_build_get_schedule (build);
  isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
  int dimension = isl_space_dim (schedule_space, isl_dim_out);
  for_info->is_parallelizable =
    !carries_deps (schedule, dependences, dimension);
  isl_union_map_free (schedule);
  isl_space_free (schedule_space);
  isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
  return id;
}

/* Generate isl AST from schedule of SCOP.  */

__isl_give isl_ast_node *translate_isl_ast_to_gimple::
scop_to_isl_ast (scop_p scop)
{
  int old_err = isl_options_get_on_error (scop->isl_context);
  int old_max_operations = isl_ctx_get_max_operations (scop->isl_context);
  int max_operations = param_max_isl_operations;
  if (max_operations)
    isl_ctx_set_max_operations (scop->isl_context, max_operations);
  isl_options_set_on_error (scop->isl_context, ISL_ON_ERROR_CONTINUE);

  gcc_assert (scop->transformed_schedule);

  /* Set the separate option to reduce control flow overhead.  */
  isl_schedule *schedule = isl_schedule_map_schedule_node_bottom_up
    (isl_schedule_copy (scop->transformed_schedule), set_separate_option, NULL);
  isl_ast_build *context_isl = generate_isl_context (scop);

  if (flag_loop_parallelize_all)
    {
      scop_get_dependences (scop);
      context_isl =
	isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
					   scop->dependence);
    }

  isl_ast_node *ast_isl = isl_ast_build_node_from_schedule
    (context_isl, schedule);
  isl_ast_build_free (context_isl);

  isl_options_set_on_error (scop->isl_context, old_err);
  isl_ctx_reset_operations (scop->isl_context);
  isl_ctx_set_max_operations (scop->isl_context, old_max_operations);
  if (isl_ctx_last_error (scop->isl_context) != isl_error_none)
    {
      if (dump_enabled_p ())
	{
	  dump_user_location_t loc = find_loop_location
	    (scop->scop_info->region.entry->dest->loop_father);
	  if (isl_ctx_last_error (scop->isl_context) == isl_error_quota)
	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
			     "loop nest not optimized, AST generation timed out "
			     "after %d operations [--param max-isl-operations]\n",
			     max_operations);
	  else
	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
			     "loop nest not optimized, ISL AST generation "
			     "signalled an error\n");
	}
      isl_ast_node_free (ast_isl);
      return NULL;
    }

  return ast_isl;
}

/* Generate out-of-SSA copies for the entry edge FALSE_ENTRY/TRUE_ENTRY
   in REGION.  */

static void
generate_entry_out_of_ssa_copies (edge false_entry,
				  edge true_entry,
				  sese_info_p region)
{
  gimple_stmt_iterator gsi_tgt = gsi_start_bb (true_entry->dest);
  for (gphi_iterator psi = gsi_start_phis (false_entry->dest);
       !gsi_end_p (psi); gsi_next (&psi))
    {
      gphi *phi = psi.phi ();
      tree res = gimple_phi_result (phi);
      if (virtual_operand_p (res))
	continue;
      /* When there's no out-of-SSA var registered do not bother
         to create one.  */
      tree *rename = region->rename_map->get (res);
      if (! rename)
	continue;
      tree new_phi_def = *rename;
      gassign *ass = gimple_build_assign (new_phi_def,
					  PHI_ARG_DEF_FROM_EDGE (phi,
								 false_entry));
      gsi_insert_after (&gsi_tgt, ass, GSI_NEW_STMT);
    }
}

/* GIMPLE Loop Generator: generates loops in GIMPLE form for the given SCOP.
   Return true if code generation succeeded.  */

bool
graphite_regenerate_ast_isl (scop_p scop)
{
  sese_info_p region = scop->scop_info;
  translate_isl_ast_to_gimple t (region);

  ifsese if_region = NULL;
  isl_ast_node *root_node;
  ivs_params ip;

  timevar_push (TV_GRAPHITE_CODE_GEN);
  t.add_parameters_to_ivs_params (scop, ip);
  root_node = t.scop_to_isl_ast (scop);
  if (! root_node)
    {
      ivs_params_clear (ip);
      timevar_pop (TV_GRAPHITE_CODE_GEN);
      return false;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "[scheduler] original schedule:\n");
      print_isl_schedule (dump_file, scop->original_schedule);
      fprintf (dump_file, "[scheduler] isl transformed schedule:\n");
      print_isl_schedule (dump_file, scop->transformed_schedule);

      fprintf (dump_file, "[scheduler] original ast:\n");
      print_schedule_ast (dump_file, scop->original_schedule, scop);
      fprintf (dump_file, "[scheduler] AST generated by isl:\n");
      print_isl_ast (dump_file, root_node);
    }

  if_region = move_sese_in_condition (region);
  region->if_region = if_region;

  loop_p context_loop = region->region.entry->src->loop_father;
  edge e = single_succ_edge (if_region->true_region->region.entry->dest);
  basic_block bb = split_edge (e);

  /* Update the true_region exit edge.  */
  region->if_region->true_region->region.exit = single_succ_edge (bb);

  t.translate_isl_ast (context_loop, root_node, e, ip);
  if (! t.codegen_error_p ())
    {
      generate_entry_out_of_ssa_copies (if_region->false_region->region.entry,
					if_region->true_region->region.entry,
					region);
      sese_insert_phis_for_liveouts (region,
				     if_region->region->region.exit->src,
				     if_region->false_region->region.exit,
				     if_region->true_region->region.exit);
      if (dump_file)
	fprintf (dump_file, "[codegen] isl AST to Gimple succeeded.\n");
    }

  if (t.codegen_error_p ())
    {
      if (dump_enabled_p ())
	{
	  dump_user_location_t loc = find_loop_location
	    (scop->scop_info->region.entry->dest->loop_father);
	  dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
			   "loop nest not optimized, code generation error\n");
	}

      /* Remove the unreachable region.  */
      remove_edge_and_dominated_blocks (if_region->true_region->region.entry);
      basic_block ifb = if_region->false_region->region.entry->src;
      gimple_stmt_iterator gsi = gsi_last_bb (ifb);
      gsi_remove (&gsi, true);
      if_region->false_region->region.entry->flags &= ~EDGE_FALSE_VALUE;
      if_region->false_region->region.entry->flags |= EDGE_FALLTHRU;
      /* remove_edge_and_dominated_blocks marks loops for removal but
	 doesn't actually remove them (fix that...).  */
      for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
	if (!loop->header)
	  delete_loop (loop);
    }

  /* We are delaying SSA update to after code-generating all SCOPs.
     This is because we analyzed DRs and parameters on the unmodified
     IL and thus rely on SSA update to pick up new dominating definitions
     from for example SESE liveout PHIs.  This is also for efficiency
     as SSA update does work depending on the size of the function.  */

  free (if_region->true_region);
  free (if_region->region);
  free (if_region);

  ivs_params_clear (ip);
  isl_ast_node_free (root_node);
  timevar_pop (TV_GRAPHITE_CODE_GEN);

  return !t.codegen_error_p ();
}

#endif  /* HAVE_isl */
