/* Gimple Represented as Polyhedra.
   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
   Contributed by Sebastian Pop <sebastian.pop@inria.fr>.

This file is part of GCC.

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

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

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

/* This pass converts GIMPLE to GRAPHITE, performs some loop
   transformations and then converts the resulting representation back
   to GIMPLE.  

   An early description of this pass can be found in the GCC Summit'06
   paper "GRAPHITE: Polyhedral Analyses and Optimizations for GCC".
   The wiki page http://gcc.gnu.org/wiki/Graphite contains pointers to
   the related work.  

   One important document to read is CLooG's internal manual:
   http://repo.or.cz/w/cloog-ppl.git?a=blob_plain;f=doc/cloog.texi;hb=HEAD
   that describes the data structure of loops used in this file, and
   the functions that are used for transforming the code.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
#include "rtl.h"
#include "basic-block.h"
#include "diagnostic.h"
#include "tree-flow.h"
#include "toplev.h"
#include "tree-dump.h"
#include "timevar.h"
#include "cfgloop.h"
#include "tree-chrec.h"
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
#include "tree-pass.h"
#include "domwalk.h"
#include "value-prof.h"
#include "pointer-set.h"
#include "gimple.h"

#ifdef HAVE_cloog
#include "cloog/cloog.h"
#include "graphite.h"

static VEC (scop_p, heap) *current_scops;

/* Converts a GMP constant V to a tree and returns it.  */

static tree
gmp_cst_to_tree (tree type, Value v)
{
  return build_int_cst (type, value_get_si (v));
}

/* Returns true when BB is in REGION.  */

static bool
bb_in_sese_p (basic_block bb, sese region)
{
  return pointer_set_contains (SESE_REGION_BBS (region), bb);
}

/* Returns true when LOOP is in the SESE region R.  */

static inline bool 
loop_in_sese_p (struct loop *loop, sese r)
{
  return (bb_in_sese_p (loop->header, r)
	  && bb_in_sese_p (loop->latch, r));
}

/* For a USE in BB, if BB is outside REGION, mark the USE in the
   SESE_LIVEIN and SESE_LIVEOUT sets.  */

static void
sese_build_livein_liveouts_use (sese region, basic_block bb, tree use)
{
  unsigned ver;
  basic_block def_bb;

  if (TREE_CODE (use) != SSA_NAME)
    return;

  ver = SSA_NAME_VERSION (use);
  def_bb = gimple_bb (SSA_NAME_DEF_STMT (use));
  if (!def_bb
      || !bb_in_sese_p (def_bb, region)
      || bb_in_sese_p (bb, region))
    return;

  if (!SESE_LIVEIN_VER (region, ver))
    SESE_LIVEIN_VER (region, ver) = BITMAP_ALLOC (NULL);

  bitmap_set_bit (SESE_LIVEIN_VER (region, ver), bb->index);
  bitmap_set_bit (SESE_LIVEOUT (region), ver);
}

/* Marks for rewrite all the SSA_NAMES defined in REGION and that are
   used in BB that is outside of the REGION.  */

static void
sese_build_livein_liveouts_bb (sese region, basic_block bb)
{
  gimple_stmt_iterator bsi;
  edge e;
  edge_iterator ei;
  ssa_op_iter iter;
  tree var;

  FOR_EACH_EDGE (e, ei, bb->succs)
    for (bsi = gsi_start_phis (e->dest); !gsi_end_p (bsi); gsi_next (&bsi))
      sese_build_livein_liveouts_use (region, bb,
				      PHI_ARG_DEF_FROM_EDGE (gsi_stmt (bsi), e));

  for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
    FOR_EACH_SSA_TREE_OPERAND (var, gsi_stmt (bsi), iter, SSA_OP_ALL_USES)
      sese_build_livein_liveouts_use (region, bb, var);
}

/* Build the SESE_LIVEIN and SESE_LIVEOUT for REGION.  */

void
sese_build_livein_liveouts (sese region)
{
  basic_block bb;

  SESE_LIVEOUT (region) = BITMAP_ALLOC (NULL);
  SESE_NUM_VER (region) = num_ssa_names;
  SESE_LIVEIN (region) = XCNEWVEC (bitmap, SESE_NUM_VER (region));

  FOR_EACH_BB (bb)
    sese_build_livein_liveouts_bb (region, bb);
}

/* Register basic blocks belonging to a region in a pointer set.  */

static void
register_bb_in_sese (basic_block entry_bb, basic_block exit_bb, sese region)
{
  edge_iterator ei;
  edge e;
  basic_block bb = entry_bb;

  FOR_EACH_EDGE (e, ei, bb->succs)
    {
      if (!pointer_set_contains (SESE_REGION_BBS (region), e->dest) &&
	  e->dest->index != exit_bb->index)
	{	
	  pointer_set_insert (SESE_REGION_BBS (region), e->dest);
	  register_bb_in_sese (e->dest, exit_bb, region);
	}
    }
}

/* Builds a new SESE region from edges ENTRY and EXIT.  */

sese
new_sese (edge entry, edge exit)
{
  sese res = XNEW (struct sese);

  SESE_ENTRY (res) = entry;
  SESE_EXIT (res) = exit;
  SESE_REGION_BBS (res) = pointer_set_create ();
  register_bb_in_sese (entry->dest, exit->dest, res);

  SESE_LIVEOUT (res) = NULL;
  SESE_NUM_VER (res) = 0;
  SESE_LIVEIN (res) = NULL;

  return res;
}

/* Deletes REGION.  */

void
free_sese (sese region)
{
  int i;

  for (i = 0; i < SESE_NUM_VER (region); i++)
    BITMAP_FREE (SESE_LIVEIN_VER (region, i));

  if (SESE_LIVEIN (region))
    free (SESE_LIVEIN (region));

  if (SESE_LIVEOUT (region))
    BITMAP_FREE (SESE_LIVEOUT (region));

  pointer_set_destroy (SESE_REGION_BBS (region));
  XDELETE (region);
}



/* Debug the list of old induction variables for this SCOP.  */

void
debug_oldivs (scop_p scop)
{
  int i;
  name_tree oldiv;

  fprintf (stderr, "Old IVs:");

  for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, oldiv); i++)
    {
      fprintf (stderr, "(");
      print_generic_expr (stderr, oldiv->t, 0);
      fprintf (stderr, ", %s, %d)\n", oldiv->name, oldiv->loop->num);
    }
  fprintf (stderr, "\n");
}

/* Debug the loops around basic block GB.  */

void
debug_loop_vec (graphite_bb_p gb)
{
  int i;
  loop_p loop;

  fprintf (stderr, "Loop Vec:");

  for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, loop); i++)
    fprintf (stderr, "%d: %d, ", i, loop ? loop->num : -1);

  fprintf (stderr, "\n");
}

/* Returns true if stack ENTRY is a constant.  */

static bool
iv_stack_entry_is_constant (iv_stack_entry *entry)
{
  return entry->kind == iv_stack_entry_const;
}

/* Returns true if stack ENTRY is an induction variable.  */

static bool
iv_stack_entry_is_iv (iv_stack_entry *entry)
{
  return entry->kind == iv_stack_entry_iv;
}

/* Push (IV, NAME) on STACK.  */

static void 
loop_iv_stack_push_iv (loop_iv_stack stack, tree iv, const char *name)
{
  iv_stack_entry *entry = XNEW (iv_stack_entry);
  name_tree named_iv = XNEW (struct name_tree);

  named_iv->t = iv;
  named_iv->name = name;

  entry->kind = iv_stack_entry_iv;
  entry->data.iv = named_iv;

  VEC_safe_push (iv_stack_entry_p, heap, *stack, entry);
}

/* Inserts a CONSTANT in STACK at INDEX.  */

static void
loop_iv_stack_insert_constant (loop_iv_stack stack, int index,
			       tree constant)
{
  iv_stack_entry *entry = XNEW (iv_stack_entry);
  
  entry->kind = iv_stack_entry_const;
  entry->data.constant = constant;

  VEC_safe_insert (iv_stack_entry_p, heap, *stack, index, entry);
}

/* Pops and frees an element out of STACK.  */

static void
loop_iv_stack_pop (loop_iv_stack stack)
{
  iv_stack_entry_p entry = VEC_pop (iv_stack_entry_p, *stack);

  free (entry->data.iv);
  free (entry);
}

/* Get the IV at INDEX in STACK.  */

static tree
loop_iv_stack_get_iv (loop_iv_stack stack, int index)
{
  iv_stack_entry_p entry = VEC_index (iv_stack_entry_p, *stack, index);
  iv_stack_entry_data data = entry->data;

  return iv_stack_entry_is_iv (entry) ? data.iv->t : data.constant;
}

/* Get the IV from its NAME in STACK.  */

static tree
loop_iv_stack_get_iv_from_name (loop_iv_stack stack, const char* name)
{
  int i;
  iv_stack_entry_p entry;

  for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++)
    {
      name_tree iv = entry->data.iv;
      if (!strcmp (name, iv->name))
	return iv->t;
    }

  return NULL;
}

/* Prints on stderr the contents of STACK.  */

void
debug_loop_iv_stack (loop_iv_stack stack)
{
  int i;
  iv_stack_entry_p entry;
  bool first = true;

  fprintf (stderr, "(");

  for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++)
    {
      if (first) 
	first = false;
      else
	fprintf (stderr, " ");

      if (iv_stack_entry_is_iv (entry))
	{
	  name_tree iv = entry->data.iv;
	  fprintf (stderr, "%s:", iv->name);
	  print_generic_expr (stderr, iv->t, 0);
	}
      else 
	{
	  tree constant = entry->data.constant;
	  print_generic_expr (stderr, constant, 0);
	  fprintf (stderr, ":");
	  print_generic_expr (stderr, constant, 0);
	}
    }

  fprintf (stderr, ")\n");
}

/* Frees STACK.  */

static void
free_loop_iv_stack (loop_iv_stack stack)
{
  int i;
  iv_stack_entry_p entry;

  for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++)
    {
      free (entry->data.iv);
      free (entry);
    }

  VEC_free (iv_stack_entry_p, heap, *stack);
}



/* Structure containing the mapping between the CLooG's induction
   variable and the type of the old induction variable.  */
typedef struct ivtype_map_elt
{
  tree type;
  const char *cloog_iv;
} *ivtype_map_elt;

/* Print to stderr the element ELT.  */

static void
debug_ivtype_elt (ivtype_map_elt elt)
{
  fprintf (stderr, "(%s, ", elt->cloog_iv);
  print_generic_expr (stderr, elt->type, 0);
  fprintf (stderr, ")\n");
}

/* Helper function for debug_ivtype_map.  */

static int
debug_ivtype_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
{
  struct ivtype_map_elt *entry = (struct ivtype_map_elt *) *slot;
  debug_ivtype_elt (entry);
  return 1;
}

/* Print to stderr all the elements of MAP.  */

void
debug_ivtype_map (htab_t map)
{
  htab_traverse (map, debug_ivtype_map_1, NULL);
}

/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW.  */

static inline ivtype_map_elt
new_ivtype_map_elt (const char *cloog_iv, tree type)
{
  ivtype_map_elt res;
  
  res = XNEW (struct ivtype_map_elt);
  res->cloog_iv = cloog_iv;
  res->type = type;

  return res;
}

/* Computes a hash function for database element ELT.  */

static hashval_t
ivtype_map_elt_info (const void *elt)
{
  return htab_hash_pointer (((const struct ivtype_map_elt *) elt)->cloog_iv);
}

/* Compares database elements E1 and E2.  */

static int
eq_ivtype_map_elts (const void *e1, const void *e2)
{
  const struct ivtype_map_elt *elt1 = (const struct ivtype_map_elt *) e1;
  const struct ivtype_map_elt *elt2 = (const struct ivtype_map_elt *) e2;

  return (elt1->cloog_iv == elt2->cloog_iv);
}



/* Given a CLOOG_IV, returns the type that it should have in GCC land.
   If the information is not available, i.e. in the case one of the
   transforms created the loop, just return integer_type_node.  */

static tree
gcc_type_for_cloog_iv (const char *cloog_iv, graphite_bb_p gbb)
{
  struct ivtype_map_elt tmp;
  PTR *slot;

  tmp.cloog_iv = cloog_iv;
  slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT);

  if (slot && *slot)
    return ((ivtype_map_elt) *slot)->type;

  return integer_type_node;
}

/* Inserts constants derived from the USER_STMT argument list into the
   STACK.  This is needed to map old ivs to constants when loops have
   been eliminated.  */

static void 
loop_iv_stack_patch_for_consts (loop_iv_stack stack,
				struct clast_user_stmt *user_stmt)
{
  struct clast_stmt *t;
  int index = 0;
  CloogStatement *cs = user_stmt->statement;
  graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);

  for (t = user_stmt->substitutions; t; t = t->next) 
    {
      struct clast_expr *expr = (struct clast_expr *) 
	((struct clast_assignment *)t)->RHS;
      struct clast_term *term = (struct clast_term *) expr;

      /* FIXME: What should be done with expr_bin, expr_red?  */
      if (expr->type == expr_term
	  && !term->var)
	{
	  loop_p loop = gbb_loop_at_index (gbb, index);
	  tree oldiv = oldiv_for_loop (GBB_SCOP (gbb), loop);
	  tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node;
	  tree value = gmp_cst_to_tree (type, term->val);
	  loop_iv_stack_insert_constant (stack, index, value);
	}
      index = index + 1;
    }
}

/* Removes all constants in the iv STACK.  */

static void
loop_iv_stack_remove_constants (loop_iv_stack stack)
{
  int i;
  iv_stack_entry *entry;
  
  for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry);)
    {
      if (iv_stack_entry_is_constant (entry))
	{
	  free (VEC_index (iv_stack_entry_p, *stack, i));
	  VEC_ordered_remove (iv_stack_entry_p, *stack, i);
	}
      else
	i++;
    }
}

/* Returns a new loop_to_cloog_loop_str structure.  */

static inline struct loop_to_cloog_loop_str *
new_loop_to_cloog_loop_str (int loop_num,
                            int loop_position,
                            CloogLoop *cloog_loop)
{
  struct loop_to_cloog_loop_str *result;

  result = XNEW (struct loop_to_cloog_loop_str);
  result->loop_num = loop_num;
  result->cloog_loop = cloog_loop;
  result->loop_position = loop_position;

  return result;
}

/* Hash function for SCOP_LOOP2CLOOG_LOOP hash table.  */

static hashval_t
hash_loop_to_cloog_loop (const void *elt)
{
  return ((const struct loop_to_cloog_loop_str *) elt)->loop_num;
}

/* Equality function for SCOP_LOOP2CLOOG_LOOP hash table.  */

static int
eq_loop_to_cloog_loop (const void *el1, const void *el2)
{
  const struct loop_to_cloog_loop_str *elt1, *elt2;

  elt1 = (const struct loop_to_cloog_loop_str *) el1;
  elt2 = (const struct loop_to_cloog_loop_str *) el2;
  return elt1->loop_num == elt2->loop_num;
}

/* Compares two graphite bbs and returns an integer less than, equal to, or
   greater than zero if the first argument is considered to be respectively
   less than, equal to, or greater than the second. 
   We compare using the lexicographic order of the static schedules.  */

static int 
gbb_compare (const void *p_1, const void *p_2)
{
  const struct graphite_bb *const gbb_1
    = *(const struct graphite_bb *const*) p_1;
  const struct graphite_bb *const gbb_2
    = *(const struct graphite_bb *const*) p_2;

  return lambda_vector_compare (GBB_STATIC_SCHEDULE (gbb_1),
                                gbb_nb_loops (gbb_1) + 1,
                                GBB_STATIC_SCHEDULE (gbb_2),
                                gbb_nb_loops (gbb_2) + 1);
}

/* Sort graphite bbs in SCOP.  */

static void
graphite_sort_gbbs (scop_p scop)
{
  VEC (graphite_bb_p, heap) *bbs = SCOP_BBS (scop);

  qsort (VEC_address (graphite_bb_p, bbs),
         VEC_length (graphite_bb_p, bbs),
         sizeof (graphite_bb_p), gbb_compare);
}

/* Dump conditions of a graphite basic block GBB on FILE.  */

static void
dump_gbb_conditions (FILE *file, graphite_bb_p gbb)
{
  int i;
  gimple stmt;
  VEC (gimple, heap) *conditions = GBB_CONDITIONS (gbb);
  
  if (VEC_empty (gimple, conditions))
    return;

  fprintf (file, "\tbb %d\t: cond = {", GBB_BB (gbb)->index);

  for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
    print_gimple_stmt (file, stmt, 0, 0);

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

/* Converts the graphite scheduling function into a cloog scattering
   matrix.  This scattering matrix is used to limit the possible cloog
   output to valid programs in respect to the scheduling function. 

   SCATTERING_DIMENSIONS specifies the dimensionality of the scattering
   matrix. CLooG 0.14.0 and previous versions require, that all scattering
   functions of one CloogProgram have the same dimensionality, therefore we
   allow to specify it. (Should be removed in future versions)  */

static CloogMatrix *
schedule_to_scattering (graphite_bb_p gb, int scattering_dimensions) 
{
  int i;
  scop_p scop = GBB_SCOP (gb);

  int nb_iterators = gbb_nb_loops (gb);

  /* The cloog scattering matrix consists of these colums:
     1                        col  = Eq/Inq,
     scattering_dimensions    cols = Scattering dimensions,
     nb_iterators             cols = bb's iterators,
     scop_nb_params        cols = Parameters,
     1                        col  = Constant 1.

     Example:

     scattering_dimensions = 5
     max_nb_iterators = 2
     nb_iterators = 1 
     scop_nb_params = 2

     Schedule:
     ? i
     4 5

     Scattering Matrix:
     s1  s2  s3  s4  s5  i   p1  p2  1 
     1   0   0   0   0   0   0   0  -4  = 0
     0   1   0   0   0  -1   0   0   0  = 0
     0   0   1   0   0   0   0   0  -5  = 0  */
  int nb_params = scop_nb_params (scop);
  int nb_cols = 1 + scattering_dimensions + nb_iterators + nb_params + 1;
  int col_const = nb_cols - 1; 
  int col_iter_offset = 1 + scattering_dimensions;

  CloogMatrix *scat = cloog_matrix_alloc (scattering_dimensions, nb_cols);

  gcc_assert (scattering_dimensions >= nb_iterators * 2 + 1);

  /* Initialize the identity matrix.  */
  for (i = 0; i < scattering_dimensions; i++)
    value_set_si (scat->p[i][i + 1], 1);

  /* Textual order outside the first loop */
  value_set_si (scat->p[0][col_const], -GBB_STATIC_SCHEDULE (gb)[0]);

  /* For all surrounding loops.  */
  for (i = 0;  i < nb_iterators; i++)
    {
      int schedule = GBB_STATIC_SCHEDULE (gb)[i + 1];

      /* Iterations of this loop.  */
      value_set_si (scat->p[2 * i + 1][col_iter_offset + i], -1);

      /* Textual order inside this loop.  */
      value_set_si (scat->p[2 * i + 2][col_const], -schedule);
    }

  return scat; 
}

/* Print the schedules of GB to FILE with INDENT white spaces before.
   VERBOSITY determines how verbose the code pretty printers are.  */

void
print_graphite_bb (FILE *file, graphite_bb_p gb, int indent, int verbosity)
{
  CloogMatrix *scattering;
  int i;
  loop_p loop;
  fprintf (file, "\nGBB (\n");

  print_loops_bb (file, GBB_BB (gb), indent+2, verbosity);

  if (GBB_DOMAIN (gb))
    {
      fprintf (file, "       (domain: \n");
      cloog_matrix_print (file, GBB_DOMAIN (gb));
      fprintf (file, "       )\n");
    }

  if (GBB_STATIC_SCHEDULE (gb))
    {
      fprintf (file, "       (static schedule: ");
      print_lambda_vector (file, GBB_STATIC_SCHEDULE (gb),
			   gbb_nb_loops (gb) + 1);
      fprintf (file, "       )\n");
    }

  if (GBB_LOOPS (gb))
    {
      fprintf (file, "       (contained loops: \n");
      for (i = 0; VEC_iterate (loop_p, GBB_LOOPS (gb), i, loop); i++)
	if (loop == NULL)
	  fprintf (file, "       iterator %d   =>  NULL \n", i); 
	else
	  fprintf (file, "       iterator %d   =>  loop %d \n", i,
		   loop->num);
      fprintf (file, "       )\n");
    }

  if (GBB_DATA_REFS (gb))
    dump_data_references (file, GBB_DATA_REFS (gb));

  if (GBB_CONDITIONS (gb))
    {
      fprintf (file, "       (conditions: \n");
      dump_gbb_conditions (file, gb);
      fprintf (file, "       )\n");
    }

  if (GBB_SCOP (gb)
      && GBB_STATIC_SCHEDULE (gb))
    {
      fprintf (file, "       (scattering: \n");
      scattering = schedule_to_scattering (gb, 2 * gbb_nb_loops (gb) + 1);
      cloog_matrix_print (file, scattering);
      cloog_matrix_free (scattering);
      fprintf (file, "       )\n");
    }

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

/* Print to STDERR the schedules of GB with VERBOSITY level.  */

void
debug_gbb (graphite_bb_p gb, int verbosity)
{
  print_graphite_bb (stderr, gb, 0, verbosity);
}


/* Print SCOP to FILE.  VERBOSITY determines how verbose the pretty
   printers are.  */

static void
print_scop (FILE *file, scop_p scop, int verbosity)
{
  if (scop == NULL)
    return;

  fprintf (file, "\nSCoP_%d_%d (\n",
	   SCOP_ENTRY (scop)->index, SCOP_EXIT (scop)->index);

  fprintf (file, "       (cloog: \n");
  cloog_program_print (file, SCOP_PROG (scop));
  fprintf (file, "       )\n");

  if (SCOP_BBS (scop))
    {
      graphite_bb_p gb;
      int i;

      for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
	print_graphite_bb (file, gb, 0, verbosity);
    }

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

/* Print all the SCOPs to FILE.  VERBOSITY determines how verbose the
   code pretty printers are.  */

static void
print_scops (FILE *file, int verbosity)
{
  int i;
  scop_p scop;

  for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
    print_scop (file, scop, verbosity);
}

/* Debug SCOP.  VERBOSITY determines how verbose the code pretty
   printers are. */

void
debug_scop (scop_p scop, int verbosity)
{
  print_scop (stderr, scop, verbosity);
}

/* Debug all SCOPs from CURRENT_SCOPS.  VERBOSITY determines how
   verbose the code pretty printers are.  */

void 
debug_scops (int verbosity)
{
  print_scops (stderr, verbosity);
}

/* Pretty print to FILE the SCOP in DOT format.  */

static void 
dot_scop_1 (FILE *file, scop_p scop)
{
  edge e;
  edge_iterator ei;
  basic_block bb;
  basic_block entry = SCOP_ENTRY (scop);
  basic_block exit = SCOP_EXIT (scop);
    
  fprintf (file, "digraph SCoP_%d_%d {\n", entry->index,
	   exit->index);

  FOR_ALL_BB (bb)
    {
      if (bb == entry)
	fprintf (file, "%d [shape=triangle];\n", bb->index);

      if (bb == exit)
	fprintf (file, "%d [shape=box];\n", bb->index);

      if (bb_in_sese_p (bb, SCOP_REGION (scop))) 
	fprintf (file, "%d [color=red];\n", bb->index);

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

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

/* Display SCOP using dotty.  */

void
dot_scop (scop_p scop)
{
  dot_scop_1 (stderr, scop);
}

/* Pretty print all SCoPs in DOT format and mark them with different colors.
   If there are not enough colors, paint later SCoPs gray.
   Special nodes:
   - "*" after the node number: entry of a SCoP,
   - "#" after the node number: exit of a SCoP,
   - "()" entry or exit not part of SCoP.  */

static void
dot_all_scops_1 (FILE *file)
{
  basic_block bb;
  edge e;
  edge_iterator ei;
  scop_p scop;
  const char* color;
  int i;

  /* Disable debugging while printing graph.  */
  int tmp_dump_flags = dump_flags;
  dump_flags = 0;

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

  FOR_ALL_BB (bb)
    {
      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.  */
      for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
	if (bb_in_sese_p (bb, SCOP_REGION (scop))
	    || (SCOP_EXIT (scop) == bb)
	    || (SCOP_ENTRY (scop) == bb))
	  {
	    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 (!bb_in_sese_p (bb, SCOP_REGION (scop)))
	      fprintf (file, " ("); 

	    if (bb == SCOP_ENTRY (scop)
		&& bb == SCOP_EXIT (scop))
	      fprintf (file, " %d*# ", bb->index);
	    else if (bb == SCOP_ENTRY (scop))
	      fprintf (file, " %d* ", bb->index);
	    else if (bb == SCOP_EXIT (scop))
	      fprintf (file, " %d# ", bb->index);
	    else
	      fprintf (file, " %d ", bb->index);

	    if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
	      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 </TD></TR>\n", bb->index);
        }

      fprintf (file, "  </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
    }

  FOR_ALL_BB (bb)
    {
      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 all SCoPs using dotty.  */

void
dot_all_scops (void)
{
  /* When debugging, enable the following code.  This cannot be used
     in production compilers because it calls "system".  */
#if 0
  FILE *stream = fopen ("/tmp/allscops.dot", "w");
  gcc_assert (stream);

  dot_all_scops_1 (stream);
  fclose (stream);

  system ("dotty /tmp/allscops.dot");
#else
  dot_all_scops_1 (stderr);
#endif
}

/* Returns the outermost loop in SCOP that contains BB.  */

static struct loop *
outermost_loop_in_scop (scop_p scop, basic_block bb)
{
  struct loop *nest;

  nest = bb->loop_father;
  while (loop_outer (nest)
	 && loop_in_sese_p (loop_outer (nest), SCOP_REGION (scop)))
    nest = loop_outer (nest);

  return nest;
}

/* Returns the block preceding the entry of SCOP.  */

static basic_block
block_before_scop (scop_p scop)
{
  return SESE_ENTRY (SCOP_REGION (scop))->src;
}

/* Return true when EXPR is an affine function in LOOP with parameters
   instantiated relative to SCOP_ENTRY.  */

static bool
loop_affine_expr (basic_block scop_entry, struct loop *loop, tree expr)
{
  int n = loop->num;
  tree scev = analyze_scalar_evolution (loop, expr);

  scev = instantiate_scev (scop_entry, loop, scev);

  return (evolution_function_is_invariant_p (scev, n)
	  || evolution_function_is_affine_multivariate_p (scev, n));
}

/* Return true if REF or any of its subtrees contains a
   component_ref.  */

static bool
contains_component_ref_p (tree ref)
{
  if (!ref)
    return false;

  while (handled_component_p (ref))
    {
      if (TREE_CODE (ref) == COMPONENT_REF)
	return true;

      ref = TREE_OPERAND (ref, 0);
    }

  return false;
}

/* Return true if the operand OP is simple.  */

static bool
is_simple_operand (loop_p loop, gimple stmt, tree op) 
{
  /* It is not a simple operand when it is a declaration,  */
  if (DECL_P (op)
      /* or a structure,  */
      || AGGREGATE_TYPE_P (TREE_TYPE (op))
      /* or a COMPONENT_REF,  */
      || contains_component_ref_p (op)
      /* or a memory access that cannot be analyzed by the data
	 reference analysis.  */
      || ((handled_component_p (op) || INDIRECT_REF_P (op))
	  && !stmt_simple_memref_p (loop, stmt, op)))
    return false;

  return true;
}

/* Return true only when STMT is simple enough for being handled by
   Graphite.  This depends on SCOP_ENTRY, as the parametetrs are
   initialized relatively to this basic block.  */

static bool
stmt_simple_for_scop_p (basic_block scop_entry, gimple stmt)
{
  basic_block bb = gimple_bb (stmt);
  struct loop *loop = bb->loop_father;

  /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
     Calls have side-effects, except those to const or pure
     functions.  */
  if (gimple_has_volatile_ops (stmt)
      || (gimple_code (stmt) == GIMPLE_CALL
	  && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
      || (gimple_code (stmt) == GIMPLE_ASM))
    return false;

  switch (gimple_code (stmt))
    {
    case GIMPLE_RETURN:
    case GIMPLE_LABEL:
      return true;

    case GIMPLE_COND:
      {
	tree op;
	ssa_op_iter op_iter;
        enum tree_code code = gimple_cond_code (stmt);

        /* We can only handle this kind of conditional expressions.  
           For inequalities like "if (i != 3 * k)" we need unions of
           polyhedrons.  Expressions like  "if (a)" or "if (a == 15)" need
           them for the else branch.  */
        if (!(code == LT_EXPR
	      || code == GT_EXPR
              || code == LE_EXPR
	      || code == GE_EXPR))
          return false;

	if (!scop_entry)
	  return false;

	FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
	  if (!loop_affine_expr (scop_entry, loop, op))
	    return false;

	return true;
      }

    case GIMPLE_ASSIGN:
      {
	enum tree_code code = gimple_assign_rhs_code (stmt);

	switch (get_gimple_rhs_class (code))
	  {
	  case GIMPLE_UNARY_RHS:
	  case GIMPLE_SINGLE_RHS:
	    return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt))
		    && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt)));

	  case GIMPLE_BINARY_RHS:
	    return (is_simple_operand (loop, stmt, gimple_assign_lhs (stmt))
		    && is_simple_operand (loop, stmt, gimple_assign_rhs1 (stmt))
		    && is_simple_operand (loop, stmt, gimple_assign_rhs2 (stmt)));

	  case GIMPLE_INVALID_RHS:
	  default:
	    gcc_unreachable ();
	  }
      }

    case GIMPLE_CALL:
      {
	size_t i;
	size_t n = gimple_call_num_args (stmt);
	tree lhs = gimple_call_lhs (stmt);

	if (lhs && !is_simple_operand (loop, stmt, lhs))
	  return false;

	for (i = 0; i < n; i++)
	  if (!is_simple_operand (loop, stmt, gimple_call_arg (stmt, i)))
	    return false;

	return true;
      }

    default:
      /* These nodes cut a new scope.  */
      return false;
    }

  return false;
}

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

static gimple
harmful_stmt_in_bb (basic_block scop_entry, basic_block bb)
{
  gimple_stmt_iterator gsi;
  gimple stmt;

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

  stmt = last_stmt (bb);
  if (stmt && gimple_code (stmt) == GIMPLE_COND)
    {
      tree lhs = gimple_cond_lhs (stmt);
      tree rhs = gimple_cond_rhs (stmt);

      if (TREE_CODE (TREE_TYPE (lhs)) == REAL_TYPE
	  || TREE_CODE (TREE_TYPE (rhs)) == REAL_TYPE)
	return stmt;
    }

  return NULL;
}

/* Returns true when BB will be represented in graphite.  Return false
   for the basic blocks that contain code eliminated in the code
   generation pass: i.e. induction variables and exit conditions.  */

static bool
graphite_stmt_p (scop_p scop, basic_block bb,
		 VEC (data_reference_p, heap) *drs)
{
  gimple_stmt_iterator gsi;
  loop_p loop = bb->loop_father;

  if (VEC_length (data_reference_p, drs) > 0)
    return true;

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

      switch (gimple_code (stmt))
        {
          /* Control flow expressions can be ignored, as they are
             represented in the iteration domains and will be
             regenerated by graphite.  */
	case GIMPLE_COND:
	case GIMPLE_GOTO:
	case GIMPLE_SWITCH:
	  break;

	case GIMPLE_ASSIGN:
	  {
	    tree var = gimple_assign_lhs (stmt);
	    var = analyze_scalar_evolution (loop, var);
	    var = instantiate_scev (block_before_scop (scop), loop, var);

	    if (chrec_contains_undetermined (var))
	      return true;

	    break;
	  }

	default:
	  return true;
        }
    }

  return false;
}

/* Store the GRAPHITE representation of BB.  */

static void
new_graphite_bb (scop_p scop, basic_block bb)
{
  struct graphite_bb *gbb;
  VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
  struct loop *nest = outermost_loop_in_scop (scop, bb);
  gimple_stmt_iterator gsi;

  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    find_data_references_in_stmt (nest, gsi_stmt (gsi), &drs);

  if (!graphite_stmt_p (scop, bb, drs))
    {
      free_data_refs (drs);
      return;
    }

  gbb = XNEW (struct graphite_bb);
  bb->aux = gbb;
  GBB_BB (gbb) = bb;
  GBB_SCOP (gbb) = scop;
  GBB_DATA_REFS (gbb) = drs;
  GBB_DOMAIN (gbb) = NULL;
  GBB_CONDITIONS (gbb) = NULL;
  GBB_CONDITION_CASES (gbb) = NULL;
  GBB_LOOPS (gbb) = NULL;
  GBB_STATIC_SCHEDULE (gbb) = NULL;
  GBB_CLOOG_IV_TYPES (gbb) = NULL;
  VEC_safe_push (graphite_bb_p, heap, SCOP_BBS (scop), gbb);
}

/* Frees GBB.  */

static void
free_graphite_bb (struct graphite_bb *gbb)
{
  if (GBB_DOMAIN (gbb))
    cloog_matrix_free (GBB_DOMAIN (gbb));

  if (GBB_CLOOG_IV_TYPES (gbb))
    htab_delete (GBB_CLOOG_IV_TYPES (gbb));

  /* FIXME: free_data_refs is disabled for the moment, but should be
     enabled.

     free_data_refs (GBB_DATA_REFS (gbb)); */

  VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
  VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
  VEC_free (loop_p, heap, GBB_LOOPS (gbb));
  GBB_BB (gbb)->aux = 0;
  XDELETE (gbb);
}



/* Structure containing the mapping between the old names and the new
   names used after block copy in the new loop context.  */
typedef struct rename_map_elt
{
  tree old_name, new_name;
} *rename_map_elt;


/* Print to stderr the element ELT.  */

static void
debug_rename_elt (rename_map_elt elt)
{
  fprintf (stderr, "(");
  print_generic_expr (stderr, elt->old_name, 0);
  fprintf (stderr, ", ");
  print_generic_expr (stderr, elt->new_name, 0);
  fprintf (stderr, ")\n");
}

/* Helper function for debug_rename_map.  */

static int
debug_rename_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
{
  struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
  debug_rename_elt (entry);
  return 1;
}

/* Print to stderr all the elements of MAP.  */

void
debug_rename_map (htab_t map)
{
  htab_traverse (map, debug_rename_map_1, NULL);
}

/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW.  */

static inline rename_map_elt
new_rename_map_elt (tree old_name, tree new_name)
{
  rename_map_elt res;
  
  res = XNEW (struct rename_map_elt);
  res->old_name = old_name;
  res->new_name = new_name;

  return res;
}

/* Computes a hash function for database element ELT.  */

static hashval_t
rename_map_elt_info (const void *elt)
{
  return htab_hash_pointer (((const struct rename_map_elt *) elt)->old_name);
}

/* Compares database elements E1 and E2.  */

static int
eq_rename_map_elts (const void *e1, const void *e2)
{
  const struct rename_map_elt *elt1 = (const struct rename_map_elt *) e1;
  const struct rename_map_elt *elt2 = (const struct rename_map_elt *) e2;

  return (elt1->old_name == elt2->old_name);
}

/* Returns the new name associated to OLD_NAME in MAP.  */

static tree
get_new_name_from_old_name (htab_t map, tree old_name)
{
  struct rename_map_elt tmp;
  PTR *slot;

  tmp.old_name = old_name;
  slot = htab_find_slot (map, &tmp, NO_INSERT);

  if (slot && *slot)
    return ((rename_map_elt) *slot)->new_name;

  return old_name;
}



/* Creates a new scop starting with ENTRY.  */

static scop_p
new_scop (edge entry, edge exit)
{
  scop_p scop = XNEW (struct scop);

  gcc_assert (entry && exit);

  SCOP_REGION (scop) = new_sese (entry, exit);
  SCOP_BBS (scop) = VEC_alloc (graphite_bb_p, heap, 3);
  SCOP_OLDIVS (scop) = VEC_alloc (name_tree, heap, 3);
  SCOP_LOOPS (scop) = BITMAP_ALLOC (NULL);
  SCOP_LOOP_NEST (scop) = VEC_alloc (loop_p, heap, 3);
  SCOP_ADD_PARAMS (scop) = true;
  SCOP_PARAMS (scop) = VEC_alloc (name_tree, heap, 3);
  SCOP_PROG (scop) = cloog_program_malloc ();
  cloog_program_set_names (SCOP_PROG (scop), cloog_names_malloc ());
  SCOP_LOOP2CLOOG_LOOP (scop) = htab_create (10, hash_loop_to_cloog_loop,
					     eq_loop_to_cloog_loop,
					     free);
  SCOP_LIVEOUT_RENAMES (scop) = htab_create (10, rename_map_elt_info,
					     eq_rename_map_elts, free);
  return scop;
}

/* Deletes SCOP.  */

static void
free_scop (scop_p scop)
{
  int i;
  name_tree p;
  struct graphite_bb *gb;
  name_tree iv;

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
    free_graphite_bb (gb);

  VEC_free (graphite_bb_p, heap, SCOP_BBS (scop));
  BITMAP_FREE (SCOP_LOOPS (scop));
  VEC_free (loop_p, heap, SCOP_LOOP_NEST (scop));

  for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++)
    free (iv);
  VEC_free (name_tree, heap, SCOP_OLDIVS (scop));
  
  for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
    free (p);

  VEC_free (name_tree, heap, SCOP_PARAMS (scop));
  cloog_program_free (SCOP_PROG (scop));
  htab_delete (SCOP_LOOP2CLOOG_LOOP (scop)); 
  htab_delete (SCOP_LIVEOUT_RENAMES (scop));
  free_sese (SCOP_REGION (scop));
  XDELETE (scop);
}

/* Deletes all scops in SCOPS.  */

static void
free_scops (VEC (scop_p, heap) *scops)
{
  int i;
  scop_p scop;

  for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
    free_scop (scop);

  VEC_free (scop_p, heap, scops);
}

typedef enum gbb_type {
  GBB_UNKNOWN,
  GBB_LOOP_SING_EXIT_HEADER,
  GBB_LOOP_MULT_EXIT_HEADER,
  GBB_LOOP_EXIT,
  GBB_COND_HEADER,
  GBB_SIMPLE,
  GBB_LAST
} gbb_type;

/* Detect the type of BB.  Loop headers are only marked, if they are
   new.  This means their loop_father is different to LAST_LOOP.
   Otherwise they are treated like any other bb and their type can be
   any other type.  */

static gbb_type
get_bb_type (basic_block bb, struct loop *last_loop)
{
  VEC (basic_block, heap) *dom;
  int nb_dom, nb_suc;
  struct loop *loop = bb->loop_father;

  /* Check, if we entry into a new loop. */
  if (loop != last_loop)
    {
      if (single_exit (loop) != NULL)
        return GBB_LOOP_SING_EXIT_HEADER;
      else if (loop->num != 0)
        return GBB_LOOP_MULT_EXIT_HEADER;
      else
	return GBB_COND_HEADER;
    }

  dom = get_dominated_by (CDI_DOMINATORS, bb);
  nb_dom = VEC_length (basic_block, dom);
  VEC_free (basic_block, heap, dom);

  if (nb_dom == 0)
    return GBB_LAST;

  nb_suc = VEC_length (edge, bb->succs);

  if (nb_dom == 1 && nb_suc == 1)
    return GBB_SIMPLE;

  return GBB_COND_HEADER;
}

/* A SCoP detection region, defined using bbs as borders. 
   All control flow touching this region, comes in passing basic_block ENTRY and
   leaves passing basic_block EXIT.  By using bbs instead of edges for the
   borders we are able to represent also regions that do not have a single
   entry or exit edge.
   But as they have a single entry basic_block and a single exit basic_block, we
   are able to generate for every sd_region a single entry and exit edge.

   1   2
    \ /
     3	<- entry
     |
     4
    / \			This region contains: {3, 4, 5, 6, 7, 8}
   5   6
   |   |
   7   8
    \ /
     9	<- exit  */


typedef struct sd_region_p
{
  /* The entry bb dominates all bbs in the sd_region.  It is part of the
     region.  */
  basic_block entry;

  /* The exit bb postdominates all bbs in the sd_region, but is not 
     part of the region.  */
  basic_block exit;
} sd_region;

DEF_VEC_O(sd_region);
DEF_VEC_ALLOC_O(sd_region, heap);


/* Moves the scops from SOURCE to TARGET and clean up SOURCE.  */

static void
move_sd_regions (VEC (sd_region, heap) **source, VEC (sd_region, heap) **target)
{
  sd_region *s;
  int i;

  for (i = 0; VEC_iterate (sd_region, *source, i, s); i++)
    VEC_safe_push (sd_region, heap, *target, s);
  
  VEC_free (sd_region, heap, *source);
}

/* Return true when it is not possible to represent the upper bound of
   LOOP in the polyhedral representation.  */

static bool
graphite_cannot_represent_loop_niter (loop_p loop)
{
  tree niter = number_of_latch_executions (loop);

  return chrec_contains_undetermined (niter)
    || !scev_is_linear_expression (niter);
}
/* Store information needed by scopdet_* functions.  */

struct scopdet_info
{
  /* Where the last open scop would stop if the current BB is harmful.  */
  basic_block last;

  /* Where the next scop would start if the current BB is harmful.  */
  basic_block next;

  /* The bb or one of its children contains open loop exits.  That means
     loop exit nodes that are not surrounded by a loop dominated by bb.  */ 
  bool exits;

  /* The bb or one of its children contains only structures we can handle.  */ 
  bool difficult;
};


static struct scopdet_info build_scops_1 (basic_block, VEC (sd_region, heap) **,
                                          loop_p);

/* Calculates BB infos. If bb is difficult we add valid SCoPs dominated by BB
   to SCOPS.  TYPE is the gbb_type of BB.  */

static struct scopdet_info 
scopdet_basic_block_info (basic_block bb, VEC (sd_region, heap) **scops,
			  gbb_type type)
{
  struct loop *loop = bb->loop_father;
  struct scopdet_info result;
  gimple stmt;

  /* XXX: ENTRY_BLOCK_PTR could be optimized in later steps.  */
  stmt = harmful_stmt_in_bb (ENTRY_BLOCK_PTR, bb);
  result.difficult = (stmt != NULL);
  result.last = NULL;

  switch (type)
    {
    case GBB_LAST:
      result.next = NULL;
      result.exits = false;
      result.last = bb;

      /* Mark bbs terminating a SESE region difficult, if they start
	 a condition.  */
      if (VEC_length (edge, bb->succs) > 1)
	result.difficult = true; 

      break;

    case GBB_SIMPLE:
      result.next = single_succ (bb);
      result.exits = false;
      result.last = bb;
      break;

    case GBB_LOOP_SING_EXIT_HEADER:
      {
        VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap,3);
        struct scopdet_info sinfo;

        sinfo = build_scops_1 (bb, &tmp_scops, loop);
	
        result.last = single_exit (bb->loop_father)->src;
        result.next = single_exit (bb->loop_father)->dest;

        /* If we do not dominate result.next, remove it.  It's either
           the EXIT_BLOCK_PTR, or another bb dominates it and will
           call the scop detection for this bb.  */
        if (!dominated_by_p (CDI_DOMINATORS, result.next, bb))
	  result.next = NULL;

	if (result.last->loop_father != loop)
	  result.next = NULL;

        if (graphite_cannot_represent_loop_niter (loop))
          result.difficult = true;

        if (sinfo.difficult)
          move_sd_regions (&tmp_scops, scops);
        else 
          VEC_free (sd_region, heap, tmp_scops);

        result.exits = false;
        result.difficult |= sinfo.difficult;
        break;
      }

    case GBB_LOOP_MULT_EXIT_HEADER:
      {
        /* XXX: For now we just do not join loops with multiple exits.  If the 
           exits lead to the same bb it may be possible to join the loop.  */
        VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3);
        VEC (edge, heap) *exits = get_loop_exit_edges (loop);
        edge e;
        int i;
        build_scops_1 (bb, &tmp_scops, loop);

	/* Scan the code dominated by this loop.  This means all bbs, that are
	   are dominated by a bb in this loop, but are not part of this loop.
	   
	   The easiest case:
	     - The loop exit destination is dominated by the exit sources.  
	 
	   TODO: We miss here the more complex cases:
		  - The exit destinations are dominated by another bb inside the
		    loop.
		  - The loop dominates bbs, that are not exit destinations.  */
        for (i = 0; VEC_iterate (edge, exits, i, e); i++)
          if (e->src->loop_father == loop
	      && dominated_by_p (CDI_DOMINATORS, e->dest, e->src))
	    {
	      /* Pass loop_outer to recognize e->dest as loop header in
		 build_scops_1.  */
	      if (e->dest->loop_father->header == e->dest)
		build_scops_1 (e->dest, &tmp_scops,
			       loop_outer (e->dest->loop_father));
	      else
		build_scops_1 (e->dest, &tmp_scops, e->dest->loop_father);
	    }

        result.next = NULL; 
        result.last = NULL;
        result.difficult = true;
        result.exits = false;
        move_sd_regions (&tmp_scops, scops);
        VEC_free (edge, heap, exits);
        break;
      }
    case GBB_COND_HEADER:
      {
	VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3);
	struct scopdet_info sinfo;
	VEC (basic_block, heap) *dominated;
	int i;
	basic_block dom_bb;
	basic_block last_bb = NULL;
	edge e;
	result.exits = false;
 
	/* First check the successors of BB, and check if it is possible to join
	   the different branches.  */
	for (i = 0; VEC_iterate (edge, bb->succs, i, e); i++)
	  {
	    /* Ignore loop exits.  They will be handled after the loop body.  */
	    if (is_loop_exit (loop, e->dest))
	      {
		result.exits = true;
		continue;
	      }

	    /* Do not follow edges that lead to the end of the
	       conditions block.  For example, in

               |   0
	       |  /|\
	       | 1 2 |
	       | | | |
	       | 3 4 |
	       |  \|/
               |   6

	       the edge from 0 => 6.  Only check if all paths lead to
	       the same node 6.  */

	    if (!single_pred_p (e->dest))
	      {
		/* Check, if edge leads directly to the end of this
		   condition.  */
		if (!last_bb)
		  {
		    last_bb = e->dest;
		  }

		if (e->dest != last_bb)
		  result.difficult = true;

		continue;
	      }

	    if (!dominated_by_p (CDI_DOMINATORS, e->dest, bb))
	      {
		result.difficult = true;
		continue;
	      }

	    sinfo = build_scops_1 (e->dest, &tmp_scops, loop);

	    result.exits |= sinfo.exits;
	    result.last = sinfo.last;
	    result.difficult |= sinfo.difficult; 

	    /* Checks, if all branches end at the same point. 
	       If that is true, the condition stays joinable.
	       Have a look at the example above.  */
	    if (sinfo.last && single_succ_p (sinfo.last))
	      {
		basic_block next_tmp = single_succ (sinfo.last);
                  
		if (!last_bb)
		    last_bb = next_tmp;

		if (next_tmp != last_bb)
		  result.difficult = true;
	      }
	    else
	      result.difficult = true;
	  }

	/* If the condition is joinable.  */
	if (!result.exits && !result.difficult)
	  {
	    /* Only return a next pointer if we dominate this pointer.
	       Otherwise it will be handled by the bb dominating it.  */ 
	    if (dominated_by_p (CDI_DOMINATORS, last_bb, bb) && last_bb != bb)
	      result.next = last_bb;
	    else
	      result.next = NULL; 

	    VEC_free (sd_region, heap, tmp_scops);
	    break;
	  }

	/* Scan remaining bbs dominated by BB.  */
	dominated = get_dominated_by (CDI_DOMINATORS, bb);

	for (i = 0; VEC_iterate (basic_block, dominated, i, dom_bb); i++)
	  {
	    /* Ignore loop exits: they will be handled after the loop body.  */
	    if (loop_depth (find_common_loop (loop, dom_bb->loop_father))
		< loop_depth (loop))
	      {
		result.exits = true;
		continue;
	      }

	    /* Ignore the bbs processed above.  */
	    if (single_pred_p (dom_bb) && single_pred (dom_bb) == bb)
	      continue;

	    if (loop_depth (loop) > loop_depth (dom_bb->loop_father))
	      sinfo = build_scops_1 (dom_bb, &tmp_scops, loop_outer (loop));
	    else
	      sinfo = build_scops_1 (dom_bb, &tmp_scops, loop);
                                           
                                     
	    result.exits |= sinfo.exits; 
	    result.difficult = true;
	    result.last = NULL;
	  }

	VEC_free (basic_block, heap, dominated);

	result.next = NULL; 
	move_sd_regions (&tmp_scops, scops);

	break;
      }

    default:
      gcc_unreachable ();
    }

  return result;
}

/* Creates the SCoPs and writes entry and exit points for every SCoP.  */

static struct scopdet_info 
build_scops_1 (basic_block current, VEC (sd_region, heap) **scops, loop_p loop)
{
  bool in_scop = false;
  sd_region open_scop;
  struct scopdet_info sinfo;

  /* Initialize result.  */ 
  struct scopdet_info result;
  result.exits = false;
  result.difficult = false;
  result.next = NULL;
  result.last = NULL;
  open_scop.entry = NULL;
  open_scop.exit = NULL;
  sinfo.last = NULL;

  /* Loop over the dominance tree.  If we meet a difficult bb, close
     the current SCoP.  Loop and condition header start a new layer,
     and can only be added if all bbs in deeper layers are simple.  */
  while (current != NULL)
    {
      sinfo = scopdet_basic_block_info (current, scops, get_bb_type (current,
								     loop));

      if (!in_scop && !(sinfo.exits || sinfo.difficult))
        {
	  open_scop.entry = current;
	  open_scop.exit = NULL;
          in_scop = true;
        }
      else if (in_scop && (sinfo.exits || sinfo.difficult))
        {
	  open_scop.exit = current;
          VEC_safe_push (sd_region, heap, *scops, &open_scop); 
          in_scop = false;
        }

      result.difficult |= sinfo.difficult;
      result.exits |= sinfo.exits;

      current = sinfo.next;
    }

  /* Try to close open_scop, if we are still in an open SCoP.  */
  if (in_scop)
    {
      int i;
      edge e;

	for (i = 0; VEC_iterate (edge, sinfo.last->succs, i, e); i++)
	  if (dominated_by_p (CDI_POST_DOMINATORS, sinfo.last, e->dest))
            open_scop.exit = e->dest;

        if (!open_scop.exit && open_scop.entry != sinfo.last)
	  open_scop.exit = sinfo.last;

	if (open_scop.exit)
	  VEC_safe_push (sd_region, heap, *scops, &open_scop);
      
    }

  result.last = sinfo.last;
  return result;
}

/* Checks if a bb is contained in REGION.  */

static bool
bb_in_sd_region (basic_block bb, sd_region *region)
{
  return dominated_by_p (CDI_DOMINATORS, bb, region->entry)
	 && !(dominated_by_p (CDI_DOMINATORS, bb, region->exit)
	      && !dominated_by_p (CDI_DOMINATORS, region->entry,
				  region->exit));
}

/* Returns the single entry edge of REGION, if it does not exits NULL.  */

static edge
find_single_entry_edge (sd_region *region)
{
  edge e;
  edge_iterator ei;
  edge entry = NULL;

  FOR_EACH_EDGE (e, ei, region->entry->preds)
    if (!bb_in_sd_region (e->src, region))
      {
	if (entry)
	  {
	    entry = NULL;
	    break;
	  }

	else
	  entry = e;
      }

  return entry;
}

/* Returns the single exit edge of REGION, if it does not exits NULL.  */

static edge
find_single_exit_edge (sd_region *region)
{
  edge e;
  edge_iterator ei;
  edge exit = NULL;

  FOR_EACH_EDGE (e, ei, region->exit->preds)
    if (bb_in_sd_region (e->src, region))
      {
	if (exit)
	  {
	    exit = NULL;
	    break;
	  }

	else
	  exit = e;
      }

  return exit;
}

/* Create a single entry edge for REGION.  */

static void
create_single_entry_edge (sd_region *region)
{
  if (find_single_entry_edge (region))
    return;

  /* There are multiple predecessors for bb_3 

  |  1  2
  |  | /
  |  |/
  |  3	<- entry
  |  |\
  |  | |
  |  4 ^
  |  | |
  |  |/
  |  5

  There are two edges (1->3, 2->3), that point from outside into the region,
  and another one (5->3), a loop latch, lead to bb_3.

  We split bb_3.
  
  |  1  2
  |  | /
  |  |/
  |3.0
  |  |\     (3.0 -> 3.1) = single entry edge
  |3.1 |  	<- entry
  |  | |
  |  | |
  |  4 ^ 
  |  | |
  |  |/
  |  5

  If the loop is part of the SCoP, we have to redirect the loop latches.

  |  1  2
  |  | /
  |  |/
  |3.0
  |  |      (3.0 -> 3.1) = entry edge
  |3.1  	<- entry
  |  |\
  |  | |
  |  4 ^
  |  | |
  |  |/
  |  5  */

  if (region->entry->loop_father->header != region->entry
      || dominated_by_p (CDI_DOMINATORS,
			 loop_latch_edge (region->entry->loop_father)->src,
			 region->exit))
    {
      edge forwarder = split_block_after_labels (region->entry);
      region->entry = forwarder->dest;
    }
  else
    /* This case is never executed, as the loop headers seem always to have a
       single edge pointing from outside into the loop.  */
    gcc_unreachable ();
      
#ifdef ENABLE_CHECKING
  gcc_assert (find_single_entry_edge (region));
#endif
}

/* Check if the sd_region, mentioned in EDGE, has no exit bb.  */

static bool
sd_region_without_exit (edge e)
{
  sd_region *r = (sd_region *) e->aux;

  if (r)
    return r->exit == NULL;
  else
    return false;
}

/* Create a single exit edge for REGION.  */

static void
create_single_exit_edge (sd_region *region)
{
  edge e;
  edge_iterator ei;
  edge forwarder = NULL;
  basic_block exit;
  
  if (find_single_exit_edge (region))
    return;

  /* We create a forwarder bb (5) for all edges leaving this region
     (3->5, 4->5).  All other edges leading to the same bb, are moved
     to a new bb (6).  If these edges where part of another region (2->5)
     we update the region->exit pointer, of this region.

     To identify which edge belongs to which region we depend on the e->aux
     pointer in every edge.  It points to the region of the edge or to NULL,
     if the edge is not part of any region.

     1 2 3 4   	1->5 no region, 		2->5 region->exit = 5,
      \| |/    	3->5 region->exit = NULL, 	4->5 region->exit = NULL
        5	<- exit

     changes to

     1 2 3 4   	1->6 no region, 			2->6 region->exit = 6,
     | | \/	3->5 no region,				4->5 no region, 
     | |  5
      \| /	5->6 region->exit = 6
	6 

     Now there is only a single exit edge (5->6).  */
  exit = region->exit;
  region->exit = NULL;
  forwarder = make_forwarder_block (exit, &sd_region_without_exit, NULL);
  
  /* Unmark the edges, that are no longer exit edges.  */
  FOR_EACH_EDGE (e, ei, forwarder->src->preds)
    if (e->aux)
      e->aux = NULL;

  /* Mark the new exit edge.  */ 
  single_succ_edge (forwarder->src)->aux = region;

  /* Update the exit bb of all regions, where exit edges lead to
     forwarder->dest.  */
  FOR_EACH_EDGE (e, ei, forwarder->dest->preds)
    if (e->aux)
      ((sd_region *) e->aux)->exit = forwarder->dest;

#ifdef ENABLE_CHECKING
  gcc_assert (find_single_exit_edge (region));
#endif
}

/* Unmark the exit edges of all REGIONS.  
   See comment in "create_single_exit_edge". */

static void
unmark_exit_edges (VEC (sd_region, heap) *regions)
{
  int i;
  sd_region *s;
  edge e;
  edge_iterator ei;

  for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
    FOR_EACH_EDGE (e, ei, s->exit->preds)
      e->aux = NULL;
}


/* Mark the exit edges of all REGIONS.  
   See comment in "create_single_exit_edge". */

static void
mark_exit_edges (VEC (sd_region, heap) *regions)
{
  int i;
  sd_region *s;
  edge e;
  edge_iterator ei;

  for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
    FOR_EACH_EDGE (e, ei, s->exit->preds)
      if (bb_in_sd_region (e->src, s))
	e->aux = s;
}

/* Free and compute again all the dominators information.  */

static inline void
recompute_all_dominators (void)
{
  mark_irreducible_loops ();
  free_dominance_info (CDI_DOMINATORS);
  free_dominance_info (CDI_POST_DOMINATORS);
  calculate_dominance_info (CDI_DOMINATORS);
  calculate_dominance_info (CDI_POST_DOMINATORS);
}

/* Verifies properties that GRAPHITE should maintain during translation.  */

static inline void
graphite_verify (void)
{
#ifdef ENABLE_CHECKING
  verify_loop_structure ();
  verify_dominators (CDI_DOMINATORS);
  verify_dominators (CDI_POST_DOMINATORS);
  verify_ssa (false);
  verify_loop_closed_ssa ();
#endif
}

/* Create for all scop regions a single entry and a single exit edge.  */

static void
create_sese_edges (VEC (sd_region, heap) *regions)
{
  int i;
  sd_region *s;

  for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
    create_single_entry_edge (s);

  mark_exit_edges (regions);

  for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
    create_single_exit_edge (s);

  unmark_exit_edges (regions);

  fix_loop_structure (NULL);

#ifdef ENABLE_CHECKING
  verify_loop_structure ();
  verify_dominators (CDI_DOMINATORS);
  verify_ssa (false);
#endif
}

/* Create graphite SCoPs from an array of scop detection regions.  */

static void
build_graphite_scops (VEC (sd_region, heap) *scop_regions)
{
  int i;
  sd_region *s;

  for (i = 0; VEC_iterate (sd_region, scop_regions, i, s); i++)
    {
      edge entry = find_single_entry_edge (s); 
      edge exit = find_single_exit_edge (s);
      scop_p scop = new_scop (entry, exit);
      VEC_safe_push (scop_p, heap, current_scops, scop);

      /* Are there overlapping SCoPs?  */
#ifdef ENABLE_CHECKING
	{
	  int j;
	  sd_region *s2;

	  for (j = 0; VEC_iterate (sd_region, scop_regions, j, s2); j++)
	    if (s != s2)
	      gcc_assert (!bb_in_sd_region (s->entry, s2));
	}
#endif
    }
}

/* Find static control parts.  */

static void
build_scops (void)
{
  struct loop *loop = current_loops->tree_root;
  VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3);

  build_scops_1 (single_succ (ENTRY_BLOCK_PTR), &tmp_scops, loop);
  create_sese_edges (tmp_scops);
  build_graphite_scops (tmp_scops);
  VEC_free (sd_region, heap, tmp_scops);
}

/* Gather the basic blocks belonging to the SCOP.  */

static void
build_scop_bbs (scop_p scop)
{
  basic_block *stack = XNEWVEC (basic_block, n_basic_blocks + 1);
  sbitmap visited = sbitmap_alloc (last_basic_block);
  int sp = 0;

  sbitmap_zero (visited);
  stack[sp++] = SCOP_ENTRY (scop);

  while (sp)
    {
      basic_block bb = stack[--sp];
      int depth = loop_depth (bb->loop_father);
      int num = bb->loop_father->num;
      edge_iterator ei;
      edge e;

      /* Scop's exit is not in the scop.  Exclude also bbs, which are
	 dominated by the SCoP exit.  These are e.g. loop latches.  */
      if (TEST_BIT (visited, bb->index)
	  || dominated_by_p (CDI_DOMINATORS, bb, SCOP_EXIT (scop))
	  /* Every block in the scop is dominated by scop's entry.  */
	  || !dominated_by_p (CDI_DOMINATORS, bb, SCOP_ENTRY (scop)))
	continue;

      new_graphite_bb (scop, bb);
      SET_BIT (visited, bb->index);

      /* First push the blocks that have to be processed last.  Note
	 that this means that the order in which the code is organized
	 below is important: do not reorder the following code.  */
      FOR_EACH_EDGE (e, ei, bb->succs)
	if (! TEST_BIT (visited, e->dest->index)
	    && (int) loop_depth (e->dest->loop_father) < depth)
	  stack[sp++] = e->dest;

      FOR_EACH_EDGE (e, ei, bb->succs)
	if (! TEST_BIT (visited, e->dest->index)
	    && (int) loop_depth (e->dest->loop_father) == depth
	    && e->dest->loop_father->num != num)
	  stack[sp++] = e->dest;

      FOR_EACH_EDGE (e, ei, bb->succs)
	if (! TEST_BIT (visited, e->dest->index)
	    && (int) loop_depth (e->dest->loop_father) == depth
	    && e->dest->loop_father->num == num
	    && EDGE_COUNT (e->dest->preds) > 1)
	  stack[sp++] = e->dest;

      FOR_EACH_EDGE (e, ei, bb->succs)
	if (! TEST_BIT (visited, e->dest->index)
	    && (int) loop_depth (e->dest->loop_father) == depth
	    && e->dest->loop_father->num == num
	    && EDGE_COUNT (e->dest->preds) == 1)
	  stack[sp++] = e->dest;

      FOR_EACH_EDGE (e, ei, bb->succs)
	if (! TEST_BIT (visited, e->dest->index)
	    && (int) loop_depth (e->dest->loop_father) > depth)
	  stack[sp++] = e->dest;
    }

  free (stack);
  sbitmap_free (visited);
}

/* Returns the number of reduction phi nodes in LOOP.  */

static int
nb_reductions_in_loop (loop_p loop)
{
  int res = 0;
  gimple_stmt_iterator gsi;

  for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gimple phi = gsi_stmt (gsi);
      tree scev;
      affine_iv iv;

      if (!is_gimple_reg (PHI_RESULT (phi)))
	continue;

      scev = analyze_scalar_evolution (loop, PHI_RESULT (phi));
      scev = instantiate_parameters (loop, scev);
      if (!simple_iv (loop, loop, PHI_RESULT (phi), &iv, true))
	res++;
    }

  return res;
}

/* A LOOP is in normal form when it contains only one scalar phi node
   that defines the main induction variable of the loop, only one
   increment of the IV, and only one exit condition. */

static tree
graphite_loop_normal_form (loop_p loop)
{
  struct tree_niter_desc niter;
  tree nit;
  gimple_seq stmts;
  edge exit = single_dom_exit (loop);
  bool known_niter = number_of_iterations_exit (loop, exit, &niter, false);

  gcc_assert (known_niter);

  nit = force_gimple_operand (unshare_expr (niter.niter), &stmts, true,
			      NULL_TREE);
  if (stmts)
    gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);

  /* One IV per loop.  */
  if (nb_reductions_in_loop (loop) > 0)
    return NULL_TREE;

  return canonicalize_loop_ivs (loop, NULL, &nit);
}

/* Record LOOP as occuring in SCOP.  Returns true when the operation
   was successful.  */

static bool
scop_record_loop (scop_p scop, loop_p loop)
{
  tree induction_var;
  name_tree oldiv;

  if (bitmap_bit_p (SCOP_LOOPS (scop), loop->num))
    return true;

  bitmap_set_bit (SCOP_LOOPS (scop), loop->num);
  VEC_safe_push (loop_p, heap, SCOP_LOOP_NEST (scop), loop);

  induction_var = graphite_loop_normal_form (loop);
  if (!induction_var)
    return false;

  oldiv = XNEW (struct name_tree);
  oldiv->t = induction_var;
  oldiv->name = get_name (SSA_NAME_VAR (oldiv->t));
  oldiv->loop = loop;
  VEC_safe_push (name_tree, heap, SCOP_OLDIVS (scop), oldiv);
  return true;
}

/* Build the loop nests contained in SCOP.  Returns true when the
   operation was successful.  */

static bool
build_scop_loop_nests (scop_p scop)
{
  unsigned i;
  basic_block bb;
  struct loop *loop0, *loop1;

  FOR_EACH_BB (bb)
    if (bb_in_sese_p (bb, SCOP_REGION (scop)))
      {
	struct loop *loop = bb->loop_father;

	/* Only add loops if they are completely contained in the SCoP.  */
	if (loop->header == bb
	    && bb_in_sese_p (loop->latch, SCOP_REGION (scop)))
	  {
	    if (!scop_record_loop (scop, loop))
	      return false;
	  }
      }

  /* Make sure that the loops in the SCOP_LOOP_NEST are ordered.  It
     can be the case that an inner loop is inserted before an outer
     loop.  To avoid this, semi-sort once.  */
  for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop0); i++)
    {
      if (VEC_length (loop_p, SCOP_LOOP_NEST (scop)) == i + 1)
	break;

      loop1 = VEC_index (loop_p, SCOP_LOOP_NEST (scop), i + 1);
      if (loop0->num > loop1->num)
	{
	  VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i, loop1);
	  VEC_replace (loop_p, SCOP_LOOP_NEST (scop), i + 1, loop0);
	}
    }

  return true;
}

/* Calculate the number of loops around LOOP in the SCOP.  */

static inline int
nb_loops_around_loop_in_scop (struct loop *l, scop_p scop)
{
  int d = 0;

  for (; loop_in_sese_p (l, SCOP_REGION (scop)); d++, l = loop_outer (l));

  return d;
}

/* Calculate the number of loops around GB in the current SCOP.  */

int
nb_loops_around_gb (graphite_bb_p gb)
{
  return nb_loops_around_loop_in_scop (gbb_loop (gb), GBB_SCOP (gb));
}

/* Returns the dimensionality of an enclosing loop iteration domain
   with respect to enclosing SCoP for a given data reference REF.  The
   returned dimensionality is homogeneous (depth of loop nest + number
   of SCoP parameters + const).  */

int
ref_nb_loops (data_reference_p ref)
{
  loop_p loop = loop_containing_stmt (DR_STMT (ref));
  scop_p scop = DR_SCOP (ref);

  return nb_loops_around_loop_in_scop (loop, scop) + scop_nb_params (scop) + 2;
}

/* Build dynamic schedules for all the BBs. */

static void
build_scop_dynamic_schedules (scop_p scop)
{
  int i, dim, loop_num, row, col;
  graphite_bb_p gb;

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
    {
      loop_num = GBB_BB (gb)->loop_father->num;

      if (loop_num != 0)
        {
          dim = nb_loops_around_gb (gb);
          GBB_DYNAMIC_SCHEDULE (gb) = cloog_matrix_alloc (dim, dim);

          for (row = 0; row < GBB_DYNAMIC_SCHEDULE (gb)->NbRows; row++)
            for (col = 0; col < GBB_DYNAMIC_SCHEDULE (gb)->NbColumns; col++)
              if (row == col)
                value_set_si (GBB_DYNAMIC_SCHEDULE (gb)->p[row][col], 1);
              else
                value_set_si (GBB_DYNAMIC_SCHEDULE (gb)->p[row][col], 0);
        }
      else
        GBB_DYNAMIC_SCHEDULE (gb) = NULL;
    }
}

/* Returns the number of loops that are identical at the beginning of
   the vectors A and B.  */

static int
compare_prefix_loops (VEC (loop_p, heap) *a, VEC (loop_p, heap) *b)
{
  int i;
  loop_p ea;
  int lb;

  if (!a || !b)
    return 0;

  lb = VEC_length (loop_p, b);

  for (i = 0; VEC_iterate (loop_p, a, i, ea); i++)
    if (i >= lb
	|| ea != VEC_index (loop_p, b, i))
      return i;

  return 0;
}

/* Build for BB the static schedule.

   The STATIC_SCHEDULE is defined like this:

   A
   for (i: ...)
     {
       for (j: ...)
         {
           B
           C 
         }

       for (k: ...)
         {
           D
           E 
         }
     }
   F

   Static schedules for A to F:

     DEPTH
     0 1 2 
   A 0
   B 1 0 0
   C 1 0 1
   D 1 1 0
   E 1 1 1 
   F 2
*/

static void
build_scop_canonical_schedules (scop_p scop)
{
  int i;
  graphite_bb_p gb;
  int nb_loops = scop_nb_loops (scop);
  lambda_vector static_schedule = lambda_vector_new (nb_loops + 1);
  VEC (loop_p, heap) *loops_previous = NULL;

  /* We have to start schedules at 0 on the first component and
     because we cannot compare_prefix_loops against a previous loop,
     prefix will be equal to zero, and that index will be
     incremented before copying.  */
  static_schedule[0] = -1;

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
    {
      int prefix = compare_prefix_loops (loops_previous, GBB_LOOPS (gb));
      int nb = gbb_nb_loops (gb);

      loops_previous = GBB_LOOPS (gb);
      memset (&(static_schedule[prefix + 1]), 0, sizeof (int) * (nb_loops - prefix));
      ++static_schedule[prefix];
      GBB_STATIC_SCHEDULE (gb) = lambda_vector_new (nb + 1);
      lambda_vector_copy (static_schedule, 
			  GBB_STATIC_SCHEDULE (gb), nb + 1);
    }
}

/* Build the LOOPS vector for all bbs in SCOP.  */

static void
build_bb_loops (scop_p scop)
{
  graphite_bb_p gb;
  int i;

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
    {
      loop_p loop;
      int depth; 

      depth = nb_loops_around_gb (gb) - 1; 

      GBB_LOOPS (gb) = VEC_alloc (loop_p, heap, 3);
      VEC_safe_grow_cleared (loop_p, heap, GBB_LOOPS (gb), depth + 1);

      loop = GBB_BB (gb)->loop_father;  

      while (scop_contains_loop (scop, loop))
        {
          VEC_replace (loop_p, GBB_LOOPS (gb), depth, loop);
          loop = loop_outer (loop);
          depth--;
        }
    }
}

/* Get the index for parameter VAR in SCOP.  */

static int
param_index (tree var, scop_p scop)
{
  int i;
  name_tree p;
  name_tree nvar;

  gcc_assert (TREE_CODE (var) == SSA_NAME);

  for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
    if (p->t == var)
      return i;

  gcc_assert (SCOP_ADD_PARAMS (scop));

  nvar = XNEW (struct name_tree);
  nvar->t = var;
  nvar->name = NULL;
  VEC_safe_push (name_tree, heap, SCOP_PARAMS (scop), nvar);
  return VEC_length (name_tree, SCOP_PARAMS (scop)) - 1;
}

/* Scan EXPR and translate it to an inequality vector INEQ that will
   be added, or subtracted, in the constraint domain matrix C at row
   R.  K is the number of columns for loop iterators in C. */ 

static void
scan_tree_for_params (scop_p s, tree e, CloogMatrix *c, int r, Value k,
		      bool subtract)
{
  int cst_col, param_col;

  if (e == chrec_dont_know)
    return;

  switch (TREE_CODE (e))
    {
    case POLYNOMIAL_CHREC:
      {
	tree left = CHREC_LEFT (e);
	tree right = CHREC_RIGHT (e);
	int var = CHREC_VARIABLE (e);

	if (TREE_CODE (right) != INTEGER_CST)
	  return;

	if (c)
	  {
            int loop_col = scop_gimple_loop_depth (s, get_loop (var)) + 1;

            if (subtract)
              value_sub_int (c->p[r][loop_col], c->p[r][loop_col],
                             int_cst_value (right));
            else
              value_add_int (c->p[r][loop_col], c->p[r][loop_col],
                             int_cst_value (right));
	  }

	switch (TREE_CODE (left))
	  {
	  case POLYNOMIAL_CHREC:
	    scan_tree_for_params (s, left, c, r, k, subtract);
            return;

	  case INTEGER_CST:
	    /* Constant part.  */
	    if (c)
	      {
                int v = int_cst_value (left);
                cst_col = c->NbColumns - 1;

                if (v < 0)
                  {
                    v = -v;
                    subtract = subtract ? false : true;
                  }

                if (subtract)
                  value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v);
                else
                  value_add_int (c->p[r][cst_col], c->p[r][cst_col], v);
	      }
	    return;

	  default:
	    scan_tree_for_params (s, left, c, r, k, subtract);
	    return;
	  }
      }
      break;

    case MULT_EXPR:
      if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
	{
	  if (c)
	    {
	      Value val;
	      gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
	      value_init (val);
	      value_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
	      value_multiply (k, k, val);
	      value_clear (val);
	    }
	  scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
	}
      else
	{
	  if (c)
	    {
	      Value val;
	      gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
	      value_init (val);
	      value_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
	      value_multiply (k, k, val);
	      value_clear (val);
	    }
	  scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
	}
      break;

    case PLUS_EXPR:
    case POINTER_PLUS_EXPR:
      scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
      scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, subtract);
      break;

    case MINUS_EXPR:
      scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
      scan_tree_for_params (s, TREE_OPERAND (e, 1), c, r, k, !subtract);
      break;

    case NEGATE_EXPR:
      scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, !subtract);
      break;

    case SSA_NAME:
      param_col = param_index (e, s);

      if (c)
	{
          param_col += c->NbColumns - scop_nb_params (s) - 1;

          if (subtract)
	    value_subtract (c->p[r][param_col], c->p[r][param_col], k);
          else
	    value_addto (c->p[r][param_col], c->p[r][param_col], k);
	}
      break;

    case INTEGER_CST:
      if (c)
	{
          int v = int_cst_value (e);
	  cst_col = c->NbColumns - 1;

          if (v < 0)
          {
            v = -v;
            subtract = subtract ? false : true;
          }
                
          if (subtract)
            value_sub_int (c->p[r][cst_col], c->p[r][cst_col], v); 
          else
            value_add_int (c->p[r][cst_col], c->p[r][cst_col], v);
	}
      break;

    CASE_CONVERT:
    case NON_LVALUE_EXPR:
      scan_tree_for_params (s, TREE_OPERAND (e, 0), c, r, k, subtract);
      break;

    default:
      gcc_unreachable ();
      break;
    }
}

/* Data structure for idx_record_params.  */

struct irp_data
{
  struct loop *loop;
  scop_p scop;
};

/* For a data reference with an ARRAY_REF as its BASE, record the
   parameters occurring in IDX.  DTA is passed in as complementary
   information, and is used by the automatic walker function.  This
   function is a callback for for_each_index.  */

static bool
idx_record_params (tree base, tree *idx, void *dta)
{
  struct irp_data *data = (struct irp_data *) dta;

  if (TREE_CODE (base) != ARRAY_REF)
    return true;

  if (TREE_CODE (*idx) == SSA_NAME)
    {
      tree scev;
      scop_p scop = data->scop;
      struct loop *loop = data->loop;
      Value one;

      scev = analyze_scalar_evolution (loop, *idx);
      scev = instantiate_scev (block_before_scop (scop), loop, scev);

      value_init (one);
      value_set_si (one, 1);
      scan_tree_for_params (scop, scev, NULL, 0, one, false);
      value_clear (one);
    }

  return true;
}

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

static void
find_params_in_bb (scop_p scop, graphite_bb_p gb)
{
  int i;
  data_reference_p dr;
  gimple stmt;
  loop_p father = GBB_BB (gb)->loop_father;

  for (i = 0; VEC_iterate (data_reference_p, GBB_DATA_REFS (gb), i, dr); i++)
    {
      struct irp_data irp;

      irp.loop = father;
      irp.scop = scop;
      for_each_index (&dr->ref, idx_record_params, &irp);
    }

  /* Find parameters in conditional statements.  */ 
  for (i = 0; VEC_iterate (gimple, GBB_CONDITIONS (gb), i, stmt); i++)
    {
      Value one;
      loop_p loop = father;

      tree lhs, rhs;

      lhs = gimple_cond_lhs (stmt);
      lhs = analyze_scalar_evolution (loop, lhs);
      lhs = instantiate_scev (block_before_scop (scop), loop, lhs);

      rhs = gimple_cond_rhs (stmt);
      rhs = analyze_scalar_evolution (loop, rhs);
      rhs = instantiate_scev (block_before_scop (scop), loop, rhs);

      value_init (one);
      scan_tree_for_params (scop, lhs, NULL, 0, one, false);
      value_set_si (one, 1);
      scan_tree_for_params (scop, rhs, NULL, 0, one, false);
      value_clear (one);
    }
}

/* Saves in NV the name of variable P->T.  */

static void
save_var_name (char **nv, int i, name_tree p)
{
  const char *name = get_name (SSA_NAME_VAR (p->t));

  if (name)
    {
      int len = strlen (name) + 16;
      nv[i] = XNEWVEC (char, len);
      snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p->t));
    }
  else
    {
      nv[i] = XNEWVEC (char, 16);
      snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p->t));
    }

  p->name = nv[i];
}

/* Return the maximal loop depth in SCOP.  */

static int
scop_max_loop_depth (scop_p scop)
{
  int i;
  graphite_bb_p gbb;
  int max_nb_loops = 0;

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++) 
    {    
      int nb_loops = gbb_nb_loops (gbb);
      if (max_nb_loops < nb_loops)
        max_nb_loops = nb_loops;
    }    

  return max_nb_loops;
}

/* Initialize Cloog's parameter names from the names used in GIMPLE.
   Initialize Cloog's iterator names, using 'graphite_iterator_%d'
   from 0 to scop_nb_loops (scop).  */

static void
initialize_cloog_names (scop_p scop)
{
  int i, nb_params = VEC_length (name_tree, SCOP_PARAMS (scop));
  char **params = XNEWVEC (char *, nb_params);
  int nb_iterators = scop_max_loop_depth (scop);
  int nb_scattering= cloog_program_nb_scattdims (SCOP_PROG (scop));
  char **iterators = XNEWVEC (char *, nb_iterators * 2);
  char **scattering = XNEWVEC (char *, nb_scattering);
  name_tree p;

  for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++)
    save_var_name (params, i, p);

  cloog_names_set_nb_parameters (cloog_program_names (SCOP_PROG (scop)),
				 nb_params);
  cloog_names_set_parameters (cloog_program_names (SCOP_PROG (scop)),
			      params);

  for (i = 0; i < nb_iterators; i++)
    {
      int len = 18 + 16;
      iterators[i] = XNEWVEC (char, len);
      snprintf (iterators[i], len, "graphite_iterator_%d", i);
    }

  cloog_names_set_nb_iterators (cloog_program_names (SCOP_PROG (scop)),
				nb_iterators);
  cloog_names_set_iterators (cloog_program_names (SCOP_PROG (scop)),
			     iterators);

  for (i = 0; i < nb_scattering; i++)
    {
      int len = 2 + 16;
      scattering[i] = XNEWVEC (char, len);
      snprintf (scattering[i], len, "s_%d", i);
    }

  cloog_names_set_nb_scattering (cloog_program_names (SCOP_PROG (scop)),
				 nb_scattering);
  cloog_names_set_scattering (cloog_program_names (SCOP_PROG (scop)),
			      scattering);
}

/* 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)
{
  graphite_bb_p gb;
  unsigned i;
  struct loop *loop;
  Value one;

  value_init (one);
  value_set_si (one, 1);

  /* Find the parameters used in the loop bounds.  */
  for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
    {
      tree nb_iters = number_of_latch_executions (loop);

      if (!chrec_contains_symbols (nb_iters))
	continue;

      nb_iters = analyze_scalar_evolution (loop, nb_iters);
      nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);
      scan_tree_for_params (scop, nb_iters, NULL, 0, one, false);
    }

  value_clear (one);

  /* Find the parameters used in data accesses.  */
  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
    find_params_in_bb (scop, gb);

  SCOP_ADD_PARAMS (scop) = false;
}

/* Build the context constraints for SCOP: constraints and relations
   on parameters.  */

static void
build_scop_context (scop_p scop)
{
  int nb_params = scop_nb_params (scop);
  CloogMatrix *matrix = cloog_matrix_alloc (1, nb_params + 2);

  /* Insert '0 >= 0' in the context matrix, as it is not allowed to be
     empty. */
 
  value_set_si (matrix->p[0][0], 1);

  value_set_si (matrix->p[0][nb_params + 1], 0);

  cloog_program_set_context (SCOP_PROG (scop),
			     cloog_domain_matrix2domain (matrix));
  cloog_matrix_free (matrix);
}

/* Returns a graphite_bb from BB.  */

static inline graphite_bb_p
gbb_from_bb (basic_block bb)
{
  return (graphite_bb_p) bb->aux;
}

/* Builds the constraint matrix for LOOP in SCOP.  NB_OUTER_LOOPS is the
   number of loops surrounding LOOP in SCOP.  OUTER_CSTR gives the
   constraints matrix for the surrounding loops.  */

static void
build_loop_iteration_domains (scop_p scop, struct loop *loop,
                              CloogMatrix *outer_cstr, int nb_outer_loops)
{
  int i, j, row;
  CloogMatrix *cstr;
  graphite_bb_p gb;

  int nb_rows = outer_cstr->NbRows + 1;
  int nb_cols = outer_cstr->NbColumns + 1;

  /* Last column of CSTR is the column of constants.  */
  int cst_col = nb_cols - 1;

  /* The column for the current loop is just after the columns of
     other outer loops.  */
  int loop_col = nb_outer_loops + 1;

  tree nb_iters = number_of_latch_executions (loop);

  /* When the number of iterations is a constant or a parameter, we
     add a constraint for the upper bound of the loop.  So add a row
     to the constraint matrix before allocating it.  */
  if (TREE_CODE (nb_iters) == INTEGER_CST
      || !chrec_contains_undetermined (nb_iters))
    nb_rows++;

  cstr = cloog_matrix_alloc (nb_rows, nb_cols);

  /* Copy the outer constraints.  */
  for (i = 0; i < outer_cstr->NbRows; i++)
    {
      /* Copy the eq/ineq and loops columns.  */
      for (j = 0; j < loop_col; j++)
        value_assign (cstr->p[i][j], outer_cstr->p[i][j]);

      /* Leave an empty column in CSTR for the current loop, and then
	 copy the parameter columns.  */
      for (j = loop_col; j < outer_cstr->NbColumns; j++)
        value_assign (cstr->p[i][j + 1], outer_cstr->p[i][j]);
    }

  /* 0 <= loop_i */
  row = outer_cstr->NbRows;
  value_set_si (cstr->p[row][0], 1);
  value_set_si (cstr->p[row][loop_col], 1);

  /* loop_i <= nb_iters */
  if (TREE_CODE (nb_iters) == INTEGER_CST)
    {
      row++;
      value_set_si (cstr->p[row][0], 1);
      value_set_si (cstr->p[row][loop_col], -1);

      value_set_si (cstr->p[row][cst_col],
		    int_cst_value (nb_iters));
    }
  else if (!chrec_contains_undetermined (nb_iters))
    {
      /* Otherwise nb_iters contains parameters: scan the nb_iters
	 expression and build its matrix representation.  */
      Value one;

      row++;
      value_set_si (cstr->p[row][0], 1);
      value_set_si (cstr->p[row][loop_col], -1);

      nb_iters = analyze_scalar_evolution (loop, nb_iters);
      nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);

      value_init (one);
      value_set_si (one, 1);
      scan_tree_for_params (scop, nb_iters, cstr, row, one, false);
      value_clear (one);
    }
  else
    gcc_unreachable ();

  if (loop->inner && loop_in_sese_p (loop->inner, SCOP_REGION (scop)))
    build_loop_iteration_domains (scop, loop->inner, cstr, nb_outer_loops + 1);

  /* Only go to the next loops, if we are not at the outermost layer.  These
     have to be handled seperately, as we can be sure, that the chain at this
     layer will be connected.  */
  if (nb_outer_loops != 0 && loop->next && loop_in_sese_p (loop->next,
							   SCOP_REGION (scop)))
    build_loop_iteration_domains (scop, loop->next, outer_cstr, nb_outer_loops);

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
    if (gbb_loop (gb) == loop)
      GBB_DOMAIN (gb) = cloog_matrix_copy (cstr);

  cloog_matrix_free (cstr);
}

/* Add conditions to the domain of GB.  */

static void
add_conditions_to_domain (graphite_bb_p gb)
{
  unsigned int i,j;
  gimple stmt;
  VEC (gimple, heap) *conditions = GBB_CONDITIONS (gb);
  CloogMatrix *domain = GBB_DOMAIN (gb);
  scop_p scop = GBB_SCOP (gb);

  unsigned nb_rows;
  unsigned nb_cols;
  unsigned nb_new_rows = 0;
  unsigned row;

  if (VEC_empty (gimple, conditions))
    return;

  if (domain)
    {
      nb_rows = domain->NbRows;
      nb_cols = domain->NbColumns;
    }
  else  
    {
      nb_rows = 0;
      nb_cols = nb_loops_around_gb (gb) + scop_nb_params (scop) + 2;
    }

  /* Count number of necessary new rows to add the conditions to the
     domain.  */
  for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
    {
      switch (gimple_code (stmt))
        {
        case GIMPLE_COND:
          {
            enum tree_code code = gimple_cond_code (stmt);

            switch (code)
              {
              case NE_EXPR:
              case EQ_EXPR:
                /* NE and EQ statements are not supported right know. */
                gcc_unreachable ();
                break;
              case LT_EXPR:
              case GT_EXPR:
              case LE_EXPR:
              case GE_EXPR:
                nb_new_rows++;
                break;
              default:
                gcc_unreachable ();
                break;
              }
          break;
          }
        case SWITCH_EXPR:
          /* Switch statements are not supported right know.  */
          gcc_unreachable ();
          break;

        default:
          gcc_unreachable ();
          break;
        }
    }


  /* Enlarge the matrix.  */ 
  { 
    CloogMatrix *new_domain;
    new_domain = cloog_matrix_alloc (nb_rows + nb_new_rows, nb_cols);

    if (domain)
      {
	for (i = 0; i < nb_rows; i++)
	  for (j = 0; j < nb_cols; j++)
	    value_assign (new_domain->p[i][j], domain->p[i][j]);

	cloog_matrix_free (domain);
      }

    domain = new_domain;
    GBB_DOMAIN (gb) = new_domain;
  }

  /* Add the conditions to the new enlarged domain matrix.  */
  row = nb_rows;
  for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
    {
      switch (gimple_code (stmt))
        {
        case GIMPLE_COND:
          {
            Value one;
            enum tree_code code;
            tree left;
            tree right;
            loop_p loop = GBB_BB (gb)->loop_father;

            left = gimple_cond_lhs (stmt);
            right = gimple_cond_rhs (stmt);

            left = analyze_scalar_evolution (loop, left);
            right = analyze_scalar_evolution (loop, right);

            left = instantiate_scev (block_before_scop (scop), loop, left);
            right = instantiate_scev (block_before_scop (scop), loop, right);

            code = gimple_cond_code (stmt);

            /* The conditions for ELSE-branches are inverted.  */
            if (VEC_index (gimple, gb->condition_cases, i) == NULL)
              code = invert_tree_comparison (code, false);

            switch (code)
              {
              case NE_EXPR:
                /* NE statements are not supported right know. */
                gcc_unreachable ();
                break;
              case EQ_EXPR:
                value_set_si (domain->p[row][0], 1);
                value_init (one);
                value_set_si (one, 1);
                scan_tree_for_params (scop, left, domain, row, one, true);
                value_set_si (one, 1);
                scan_tree_for_params (scop, right, domain, row, one, false);
                row++;
                value_set_si (domain->p[row][0], 1);
                value_set_si (one, 1);
                scan_tree_for_params (scop, left, domain, row, one, false);
                value_set_si (one, 1);
                scan_tree_for_params (scop, right, domain, row, one, true);
                value_clear (one);
                row++;
                break;
              case LT_EXPR:
                value_set_si (domain->p[row][0], 1);
                value_init (one);
                value_set_si (one, 1);
                scan_tree_for_params (scop, left, domain, row, one, true);
                value_set_si (one, 1);
                scan_tree_for_params (scop, right, domain, row, one, false);
                value_sub_int (domain->p[row][nb_cols - 1],
                    domain->p[row][nb_cols - 1], 1); 
                value_clear (one);
                row++;
                break;
              case GT_EXPR:
                value_set_si (domain->p[row][0], 1);
                value_init (one);
                value_set_si (one, 1);
                scan_tree_for_params (scop, left, domain, row, one, false);
                value_set_si (one, 1);
                scan_tree_for_params (scop, right, domain, row, one, true);
                value_sub_int (domain->p[row][nb_cols - 1],
                    domain->p[row][nb_cols - 1], 1);
                value_clear (one);
                row++;
                break;
              case LE_EXPR:
                value_set_si (domain->p[row][0], 1);
                value_init (one);
                value_set_si (one, 1);
                scan_tree_for_params (scop, left, domain, row, one, true);
                value_set_si (one, 1);
                scan_tree_for_params (scop, right, domain, row, one, false);
                value_clear (one);
                row++;
                break;
              case GE_EXPR:
                value_set_si (domain->p[row][0], 1);
                value_init (one);
                value_set_si (one, 1);
                scan_tree_for_params (scop, left, domain, row, one, false);
                value_set_si (one, 1);
                scan_tree_for_params (scop, right, domain, row, one, true);
                value_clear (one);
                row++;
                break;
              default:
                gcc_unreachable ();
                break;
              }
            break;
          }
        case GIMPLE_SWITCH:
          /* Switch statements are not supported right know.  */
          gcc_unreachable ();
          break;

        default:
          gcc_unreachable ();
          break;
        }
    }
}

/* Returns true when PHI defines an induction variable in the loop
   containing the PHI node.  */

static bool
phi_node_is_iv (gimple phi)
{
  loop_p loop = gimple_bb (phi)->loop_father;
  tree scev = analyze_scalar_evolution (loop, gimple_phi_result (phi));

  return tree_contains_chrecs (scev, NULL);
}

/* Returns true when BB contains scalar phi nodes that are not an
   induction variable of a loop.  */

static bool
bb_contains_non_iv_scalar_phi_nodes (basic_block bb)
{
  gimple phi = NULL;
  gimple_stmt_iterator si;

  for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
    if (is_gimple_reg (gimple_phi_result (gsi_stmt (si))))
      {
	/* Store the unique scalar PHI node: at this point, loops
	   should be in cannonical form, so we expect to see at most
	   one scalar phi node in the loop header.  */
	if (phi
	    || bb != bb->loop_father->header)
	  return true;

	phi = gsi_stmt (si);
      }

  if (!phi
      || phi_node_is_iv (phi))
    return false;

  return true;
}

/* Helper recursive function.  Record in CONDITIONS and CASES all
   conditions from 'if's and 'switch'es occurring in BB from SCOP.

   Returns false when the conditions contain scalar computations that
   depend on the condition, i.e. when there are scalar phi nodes on
   the junction after the condition.  Only the computations occurring
   on memory can be handled in the polyhedral model: operations that
   define scalar evolutions in conditions, that can potentially be
   used to index memory, can't be handled by the polyhedral model.  */

static bool
build_scop_conditions_1 (VEC (gimple, heap) **conditions,
			 VEC (gimple, heap) **cases, basic_block bb,
			 scop_p scop)
{
  bool res = true;
  int i, j;
  graphite_bb_p gbb;
  basic_block bb_child, bb_iter;
  VEC (basic_block, heap) *dom;
  gimple stmt;
  
  /* Make sure we are in the SCoP.  */
  if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
    return true;

  if (bb_contains_non_iv_scalar_phi_nodes (bb))
    return false;

  gbb = gbb_from_bb (bb);
  if (gbb)
    {
      GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
      GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
    }

  dom = get_dominated_by (CDI_DOMINATORS, bb);

  stmt = last_stmt (bb);
  if (stmt)
    {
      VEC (edge, gc) *edges;
      edge e;

      switch (gimple_code (stmt))
	{
	case GIMPLE_COND:
	  edges = bb->succs;
	  for (i = 0; VEC_iterate (edge, edges, i, e); i++)
	    if ((dominated_by_p (CDI_DOMINATORS, e->dest, bb))
		&& VEC_length (edge, e->dest->preds) == 1)
	      {
		/* Remove the scanned block from the dominator successors.  */
		for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++)
		  if (bb_iter == e->dest)
		    {
		      VEC_unordered_remove (basic_block, dom, j);
		      break;
		    }

		/* Recursively scan the then or else part.  */
		if (e->flags & EDGE_TRUE_VALUE)
		  VEC_safe_push (gimple, heap, *cases, stmt);
		else 
		  {
		    gcc_assert (e->flags & EDGE_FALSE_VALUE);
		    VEC_safe_push (gimple, heap, *cases, NULL);
		  }

		VEC_safe_push (gimple, heap, *conditions, stmt);
		if (!build_scop_conditions_1 (conditions, cases, e->dest, scop))
		  {
		    res = false;
		    goto done;
		  }
		VEC_pop (gimple, *conditions);
		VEC_pop (gimple, *cases);
	      }
	  break;

	case GIMPLE_SWITCH:
	  {
	    unsigned i;
	    gimple_stmt_iterator gsi_search_gimple_label;

	    for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
	      {
		basic_block bb_iter;
		size_t k;
		size_t n_cases = VEC_length (gimple, *conditions);
		unsigned n = gimple_switch_num_labels (stmt);

		bb_child = label_to_block
		  (CASE_LABEL (gimple_switch_label (stmt, i)));

		for (k = 0; k < n; k++)
		  if (i != k
		      && label_to_block 
		      (CASE_LABEL (gimple_switch_label (stmt, k))) == bb_child)
		    break;

		/* Switches with multiple case values for the same
		   block are not handled.  */
		if (k != n
		    /* Switch cases with more than one predecessor are
		       not handled.  */
		    || VEC_length (edge, bb_child->preds) != 1)
		  {
		    res = false;
		    goto done;
		  }

		/* Recursively scan the corresponding 'case' block.  */
		for (gsi_search_gimple_label = gsi_start_bb (bb_child);
		     !gsi_end_p (gsi_search_gimple_label);
		     gsi_next (&gsi_search_gimple_label))
		  {
		    gimple label = gsi_stmt (gsi_search_gimple_label);

		    if (gimple_code (label) == GIMPLE_LABEL)
		      {
			tree t = gimple_label_label (label);

			gcc_assert (t == gimple_switch_label (stmt, i));
			VEC_replace (gimple, *cases, n_cases, label);
			break;
		      }
		  }

		if (!build_scop_conditions_1 (conditions, cases, bb_child, scop))
		  {
		    res = false;
		    goto done;
		  }

		/* Remove the scanned block from the dominator successors.  */
		for (j = 0; VEC_iterate (basic_block, dom, j, bb_iter); j++)
		  if (bb_iter == bb_child)
		    {
		      VEC_unordered_remove (basic_block, dom, j);
		      break;
		    }
	      }

	    VEC_pop (gimple, *conditions);
	    VEC_pop (gimple, *cases);
	    break;
	  }

	default:
	  break;
      }
  }

  /* Scan all immediate dominated successors.  */
  for (i = 0; VEC_iterate (basic_block, dom, i, bb_child); i++)
    if (!build_scop_conditions_1 (conditions, cases, bb_child, scop))
      {
	res = false;
	goto done;
      }

 done:
  VEC_free (basic_block, heap, dom);
  return res;
}

/* Record all conditions from SCOP.

   Returns false when the conditions contain scalar computations that
   depend on the condition, i.e. when there are scalar phi nodes on
   the junction after the condition.  Only the computations occurring
   on memory can be handled in the polyhedral model: operations that
   define scalar evolutions in conditions, that can potentially be
   used to index memory, can't be handled by the polyhedral model.  */

static bool
build_scop_conditions (scop_p scop)
{
  bool res;
  VEC (gimple, heap) *conditions = NULL;
  VEC (gimple, heap) *cases = NULL;

  res = build_scop_conditions_1 (&conditions, &cases, SCOP_ENTRY (scop), scop);

  VEC_free (gimple, heap, conditions);
  VEC_free (gimple, heap, cases);
  return res;
}

/* Traverses all the GBBs of the SCOP and add their constraints to the
   iteration domains.  */

static void
add_conditions_to_constraints (scop_p scop)
{
  int i;
  graphite_bb_p gbb;

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
    add_conditions_to_domain (gbb);
}

/* Build the current domain matrix: the loops belonging to the current
   SCOP, and that vary for the execution of the current basic block.
   Returns false if there is no loop in SCOP.  */

static bool
build_scop_iteration_domain (scop_p scop)
{
  struct loop *loop;
  CloogMatrix *outer_cstr;
  int i;

  /* Build cloog loop for all loops, that are in the uppermost loop layer of
     this SCoP.  */
  for (i = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), i, loop); i++)
    if (!loop_in_sese_p (loop_outer (loop), SCOP_REGION (scop)))
      {
        /* The outermost constraints is a matrix that has:
           -first column: eq/ineq boolean
           -last column: a constant
           -scop_nb_params columns for the parameters used in the scop.  */
	outer_cstr = cloog_matrix_alloc (0, scop_nb_params (scop) + 2);
	build_loop_iteration_domains (scop, loop, outer_cstr, 0);
	cloog_matrix_free (outer_cstr);
      }

  return (i != 0);
}

/* Initializes an equation CY of the access matrix using the
   information for a subscript from AF, relatively to the loop
   indexes from LOOP_NEST and parameter indexes from PARAMS.  NDIM is
   the dimension of the array access, i.e. the number of
   subscripts.  Returns true when the operation succeeds.  */

static bool
build_access_matrix_with_af (tree af, lambda_vector cy,
			     scop_p scop, int ndim)
{
  int param_col;

  switch (TREE_CODE (af))
    {
    case POLYNOMIAL_CHREC:
      {
        struct loop *outer_loop;
	tree left = CHREC_LEFT (af);
	tree right = CHREC_RIGHT (af);
	int var;

	if (TREE_CODE (right) != INTEGER_CST)
	  return false;

        outer_loop = get_loop (CHREC_VARIABLE (af));
        var = nb_loops_around_loop_in_scop (outer_loop, scop);
	cy[var] = int_cst_value (right);

	switch (TREE_CODE (left))
	  {
	  case POLYNOMIAL_CHREC:
	    return build_access_matrix_with_af (left, cy, scop, ndim);

	  case INTEGER_CST:
	    cy[ndim - 1] = int_cst_value (left);
	    return true;

	  default:
	    return build_access_matrix_with_af (left, cy, scop, ndim);
	  }
      }

    case PLUS_EXPR:
      build_access_matrix_with_af (TREE_OPERAND (af, 0), cy, scop, ndim);
      build_access_matrix_with_af (TREE_OPERAND (af, 1), cy, scop, ndim);
      return true;
      
    case MINUS_EXPR:
      build_access_matrix_with_af (TREE_OPERAND (af, 0), cy, scop, ndim);
      build_access_matrix_with_af (TREE_OPERAND (af, 1), cy, scop, ndim);
      return true;

    case INTEGER_CST:
      cy[ndim - 1] = int_cst_value (af);
      return true;

    case SSA_NAME:
      param_col = param_index (af, scop);      
      cy [ndim - scop_nb_params (scop) + param_col - 1] = 1; 
      return true;

    default:
      /* FIXME: access_fn can have parameters.  */
      return false;
    }
}

/* Initialize the access matrix in the data reference REF with respect
   to the loop nesting LOOP_NEST.  Return true when the operation
   succeeded.  */

static bool
build_access_matrix (data_reference_p ref, graphite_bb_p gb)
{
  int i, ndim = DR_NUM_DIMENSIONS (ref);
  struct access_matrix *am = GGC_NEW (struct access_matrix);

  AM_MATRIX (am) = VEC_alloc (lambda_vector, gc, ndim);
  DR_SCOP (ref) = GBB_SCOP (gb);

  for (i = 0; i < ndim; i++)
    {
      lambda_vector v = lambda_vector_new (ref_nb_loops (ref));
      scop_p scop = GBB_SCOP (gb);
      tree af = DR_ACCESS_FN (ref, i);

      if (!build_access_matrix_with_af (af, v, scop, ref_nb_loops (ref)))
	return false;

      VEC_quick_push (lambda_vector, AM_MATRIX (am), v);
    }

  DR_ACCESS_MATRIX (ref) = am;
  return true;
}

/* Build the access matrices for the data references in the SCOP.  */

static void
build_scop_data_accesses (scop_p scop)
{
  int i;
  graphite_bb_p gb;

  /* FIXME: Construction of access matrix is disabled until some
     pass, like the data dependence analysis, is using it.  */
  return;

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
    {
      int j;
      data_reference_p dr;

      /* Construct the access matrix for each data ref, with respect to
	 the loop nest of the current BB in the considered SCOP.  */
      for (j = 0;
	   VEC_iterate (data_reference_p, GBB_DATA_REFS (gb), j, dr);
	   j++)
	{
	  bool res = build_access_matrix (dr, gb);

	  /* FIXME: At this point the DRs should always have an affine
	     form.  For the moment this fails as build_access_matrix
	     does not build matrices with parameters.  */
	  gcc_assert (res);
	}
    }
}

/* Returns the tree variable from the name NAME that was given in
   Cloog representation.  All the parameters are stored in PARAMS, and
   all the loop induction variables are stored in IVSTACK.

   FIXME: This is a hack, and Cloog should be fixed to not work with
   variable names represented as "char *string", but with void
   pointers that could be casted back to a tree.  The only problem in
   doing that is that Cloog's pretty printer still assumes that
   variable names are char *strings.  The solution would be to have a
   function pointer for pretty-printing that can be redirected to be
   print_generic_stmt in our case, or fprintf by default.
   ???  Too ugly to live.  */

static tree
clast_name_to_gcc (const char *name, VEC (name_tree, heap) *params, 
		   loop_iv_stack ivstack)
{
  int i;
  name_tree t;
  tree iv;

  if (params)
    for (i = 0; VEC_iterate (name_tree, params, i, t); i++)
      if (!strcmp (name, t->name))
	return t->t;

  iv = loop_iv_stack_get_iv_from_name (ivstack, name);
  if (iv)
    return iv;

  gcc_unreachable ();
}

/* Returns the maximal precision type for expressions E1 and E2.  */

static inline tree
max_precision_type (tree e1, tree e2)
{
  tree type1 = TREE_TYPE (e1);
  tree type2 = TREE_TYPE (e2);
  return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
}

static tree
clast_to_gcc_expression (tree, struct clast_expr *, VEC (name_tree, heap) *,
			 loop_iv_stack);

/* Converts a Cloog reduction expression R with reduction operation OP
   to a GCC expression tree of type TYPE.  PARAMS is a vector of
   parameters of the scop, and IVSTACK contains the stack of induction
   variables.  */

static tree
clast_to_gcc_expression_red (tree type, enum tree_code op,
			     struct clast_reduction *r,
			     VEC (name_tree, heap) *params,
			     loop_iv_stack ivstack)
{
  int i;
  tree res = clast_to_gcc_expression (type, r->elts[0], params, ivstack);

  for (i = 1; i < r->n; i++)
    {
      tree t = clast_to_gcc_expression (type, r->elts[i], params, ivstack);
      res = fold_build2 (op, type, res, t);
    }
  return res;
}

/* Converts a Cloog AST expression E back to a GCC expression tree of
   type TYPE.  PARAMS is a vector of parameters of the scop, and
   IVSTACK contains the stack of induction variables.  */

static tree
clast_to_gcc_expression (tree type, struct clast_expr *e,
			 VEC (name_tree, heap) *params,
			 loop_iv_stack ivstack)
{
  switch (e->type)
    {
    case expr_term:
      {
	struct clast_term *t = (struct clast_term *) e;

	if (t->var)
	  {
	    if (value_one_p (t->val))
	      {
		tree name = clast_name_to_gcc (t->var, params, ivstack);
		return fold_convert (type, name);
	      }

	    else if (value_mone_p (t->val))
	      {
		tree name = clast_name_to_gcc (t->var, params, ivstack);
		name = fold_convert (type, name);
		return fold_build1 (NEGATE_EXPR, type, name);
	      }
	    else
	      {
		tree name = clast_name_to_gcc (t->var, params, ivstack);
		tree cst = gmp_cst_to_tree (type, t->val);
		name = fold_convert (type, name);
		return fold_build2 (MULT_EXPR, type, cst, name);
	      }
	  }
	else
	  return gmp_cst_to_tree (type, t->val);
      }

    case expr_red:
      {
        struct clast_reduction *r = (struct clast_reduction *) e;

        switch (r->type)
          {
	  case clast_red_sum:
	    return clast_to_gcc_expression_red (type, PLUS_EXPR, r, params, ivstack);

	  case clast_red_min:
	    return clast_to_gcc_expression_red (type, MIN_EXPR, r, params, ivstack);

	  case clast_red_max:
	    return clast_to_gcc_expression_red (type, MAX_EXPR, r, params, ivstack);

	  default:
	    gcc_unreachable ();
          }
        break;
      }

    case expr_bin:
      {
	struct clast_binary *b = (struct clast_binary *) e;
	struct clast_expr *lhs = (struct clast_expr *) b->LHS;
	tree tl = clast_to_gcc_expression (type, lhs, params, ivstack);
	tree tr = gmp_cst_to_tree (type, b->RHS);

	switch (b->type)
	  {
	  case clast_bin_fdiv:
	    return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);

	  case clast_bin_cdiv:
	    return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);

	  case clast_bin_div:
	    return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);

	  case clast_bin_mod:
	    return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);

	  default:
	    gcc_unreachable ();
	  }
      }

    default:
      gcc_unreachable ();
    }

  return NULL_TREE;
}

/* Returns the type for the expression E.  */

static tree
gcc_type_for_clast_expr (struct clast_expr *e,
			 VEC (name_tree, heap) *params,
			 loop_iv_stack ivstack)
{
  switch (e->type)
    {
    case expr_term:
      {
	struct clast_term *t = (struct clast_term *) e;

	if (t->var)
	  return TREE_TYPE (clast_name_to_gcc (t->var, params, ivstack));
	else
	  return NULL_TREE;
      }

    case expr_red:
      {
        struct clast_reduction *r = (struct clast_reduction *) e;

	if (r->n == 1)
	  return gcc_type_for_clast_expr (r->elts[0], params, ivstack);
	else 
	  {
	    int i;
	    for (i = 0; i < r->n; i++)
	      {
		tree type = gcc_type_for_clast_expr (r->elts[i], params, ivstack);
		if (type)
		  return type;
	      }
	    return NULL_TREE;
	  }
      }

    case expr_bin:
      {
	struct clast_binary *b = (struct clast_binary *) e;
	struct clast_expr *lhs = (struct clast_expr *) b->LHS;
	return gcc_type_for_clast_expr (lhs, params, ivstack);
      }

    default:
      gcc_unreachable ();
    }

  return NULL_TREE;
}

/* Returns the type for the equation CLEQ.  */

static tree
gcc_type_for_clast_eq (struct clast_equation *cleq,
		       VEC (name_tree, heap) *params,
		       loop_iv_stack ivstack)
{
  tree type = gcc_type_for_clast_expr (cleq->LHS, params, ivstack);
  if (type)
    return type;

  return gcc_type_for_clast_expr (cleq->RHS, params, ivstack);
}

/* Translates a clast equation CLEQ to a tree.  */

static tree
graphite_translate_clast_equation (scop_p scop,
				   struct clast_equation *cleq,
				   loop_iv_stack ivstack)
{
  enum tree_code comp;
  tree type = gcc_type_for_clast_eq (cleq, SCOP_PARAMS (scop), ivstack);
  tree lhs = clast_to_gcc_expression (type, cleq->LHS, SCOP_PARAMS (scop), ivstack);
  tree rhs = clast_to_gcc_expression (type, cleq->RHS, SCOP_PARAMS (scop), ivstack);

  if (cleq->sign == 0)
    comp = EQ_EXPR;

  else if (cleq->sign > 0)
    comp = GE_EXPR;

  else
    comp = LE_EXPR;

  return fold_build2 (comp, type, lhs, rhs);
}

/* Creates the test for the condition in STMT.  */

static tree
graphite_create_guard_cond_expr (scop_p scop, struct clast_guard *stmt, 
				 loop_iv_stack ivstack)
{
  tree cond = NULL;
  int i;

  for (i = 0; i < stmt->n; i++)
    {
      tree eq = graphite_translate_clast_equation (scop, &stmt->eq[i], ivstack);

      if (cond)
	cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
      else
	cond = eq;
    }

  return cond;
}

/* Creates a new if region corresponding to Cloog's guard.  */

static edge 
graphite_create_new_guard (scop_p scop, edge entry_edge,
			   struct clast_guard *stmt, 
			   loop_iv_stack ivstack)
{
  tree cond_expr = graphite_create_guard_cond_expr (scop, stmt, ivstack);
  edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
  return exit_edge;
}

/* Walks a CLAST and returns the first statement in the body of a
   loop.  */

static struct clast_user_stmt *
clast_get_body_of_loop (struct clast_stmt *stmt)
{
  if (!stmt
      || CLAST_STMT_IS_A (stmt, stmt_user))
    return (struct clast_user_stmt *) stmt;

  if (CLAST_STMT_IS_A (stmt, stmt_for))
    return clast_get_body_of_loop (((struct clast_for *) stmt)->body);

  if (CLAST_STMT_IS_A (stmt, stmt_guard))
    return clast_get_body_of_loop (((struct clast_guard *) stmt)->then);

  if (CLAST_STMT_IS_A (stmt, stmt_block))
    return clast_get_body_of_loop (((struct clast_block *) stmt)->body);

  gcc_unreachable ();
}

/* Returns the induction variable for the loop that gets translated to
   STMT.  */

static tree
gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for)
{
  struct clast_user_stmt *stmt = clast_get_body_of_loop ((struct clast_stmt *) stmt_for);
  const char *cloog_iv = stmt_for->iterator;
  CloogStatement *cs = stmt->statement;
  graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);

  return gcc_type_for_cloog_iv (cloog_iv, gbb);
}

/* Creates a new LOOP corresponding to Cloog's STMT.  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.  */

static struct loop *
graphite_create_new_loop (scop_p scop, edge entry_edge,
			  struct clast_for *stmt, loop_iv_stack ivstack,
			  loop_p outer)
{
  tree type = gcc_type_for_iv_of_clast_loop (stmt);
  VEC (name_tree, heap) *params = SCOP_PARAMS (scop);
  tree lb = clast_to_gcc_expression (type, stmt->LB, params, ivstack);
  tree ub = clast_to_gcc_expression (type, stmt->UB, params, ivstack);
  tree stride = gmp_cst_to_tree (type, stmt->stride);
  tree ivvar = create_tmp_var (type, "graphiteIV");
  tree iv_before;
  loop_p loop = create_empty_loop_on_edge
    (entry_edge, lb, stride, ub, ivvar, &iv_before,
     outer ? outer : entry_edge->src->loop_father);

  add_referenced_var (ivvar);
  loop_iv_stack_push_iv (ivstack, iv_before, stmt->iterator);
  return loop;
}

/* Rename the SSA_NAMEs used in STMT and that appear in IVSTACK.  */

static void 
rename_variables_in_stmt (gimple stmt, htab_t map)
{
  ssa_op_iter iter;
  use_operand_p use_p;

  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
    {
      tree use = USE_FROM_PTR (use_p);
      tree new_name = get_new_name_from_old_name (map, use);

      replace_exp (use_p, new_name);
    }

  update_stmt (stmt);
}

/* Returns true if SSA_NAME is a parameter of SCOP.  */

static bool
is_parameter (scop_p scop, tree ssa_name)
{
  int i;
  VEC (name_tree, heap) *params = SCOP_PARAMS (scop);
  name_tree param;

  for (i = 0; VEC_iterate (name_tree, params, i, param); i++)
    if (param->t == ssa_name)
      return true;

  return false;
}

/* Returns true if NAME is an induction variable.  */

static bool
is_iv (tree name)
{
  return gimple_code (SSA_NAME_DEF_STMT (name)) == GIMPLE_PHI;
}

static void expand_scalar_variables_stmt (gimple, basic_block, scop_p,
					  htab_t);
static tree
expand_scalar_variables_expr (tree, tree, enum tree_code, tree, basic_block,
			      scop_p, htab_t, gimple_stmt_iterator *);

/* Copies at GSI all the scalar computations on which the ssa_name OP0
   depends on in the SCOP: these are all the scalar variables used in
   the definition of OP0, that are defined outside BB and still in the
   SCOP, i.e. not a parameter of the SCOP.  The expression that is
   returned contains only induction variables from the generated code:
   MAP contains the induction variables renaming mapping, and is used
   to translate the names of induction variables.  */

static tree
expand_scalar_variables_ssa_name (tree op0, basic_block bb,
				  scop_p scop, htab_t map, 
				  gimple_stmt_iterator *gsi)
{
  tree var0, var1, type;
  gimple def_stmt;
  enum tree_code subcode;
      
  if (is_parameter (scop, op0)
      || is_iv (op0))
    return get_new_name_from_old_name (map, op0);
      
  def_stmt = SSA_NAME_DEF_STMT (op0);
      
  if (gimple_bb (def_stmt) == bb)
    {
      /* If the defining statement is in the basic block already
	 we do not need to create a new expression for it, we
	 only need to ensure its operands are expanded.  */
      expand_scalar_variables_stmt (def_stmt, bb, scop, map);
      return get_new_name_from_old_name (map, op0);
    }
  else
    {
      if (gimple_code (def_stmt) != GIMPLE_ASSIGN
	  || !bb_in_sese_p (gimple_bb (def_stmt), SCOP_REGION (scop)))
	return get_new_name_from_old_name (map, op0);

      var0 = gimple_assign_rhs1 (def_stmt);
      subcode = gimple_assign_rhs_code (def_stmt);
      var1 = gimple_assign_rhs2 (def_stmt);
      type = gimple_expr_type (def_stmt);

      return expand_scalar_variables_expr (type, var0, subcode, var1, bb, scop,
					   map, gsi);
    }
}

/* Copies at GSI all the scalar computations on which the expression
   OP0 CODE OP1 depends on in the SCOP: these are all the scalar
   variables used in OP0 and OP1, defined outside BB and still defined
   in the SCOP, i.e. not a parameter of the SCOP.  The expression that
   is returned contains only induction variables from the generated
   code: MAP contains the induction variables renaming mapping, and is
   used to translate the names of induction variables.  */

static tree
expand_scalar_variables_expr (tree type, tree op0, enum tree_code code, 
			      tree op1, basic_block bb, scop_p scop, 
			      htab_t map, gimple_stmt_iterator *gsi)
{
  if (TREE_CODE_CLASS (code) == tcc_constant
      || TREE_CODE_CLASS (code) == tcc_declaration)
    return op0;

  /* For data references we have to duplicate also its memory
     indexing.  */
  if (TREE_CODE_CLASS (code) == tcc_reference)
    {
      switch (code)
	{
	case INDIRECT_REF:
	  {
	    tree old_name = TREE_OPERAND (op0, 0);
	    tree expr = expand_scalar_variables_ssa_name
	      (old_name, bb, scop, map, gsi);
	    tree new_name = force_gimple_operand_gsi (gsi, expr, true, NULL,
						      true, GSI_SAME_STMT);

	    set_symbol_mem_tag (SSA_NAME_VAR (new_name),
				symbol_mem_tag (SSA_NAME_VAR (old_name)));
	    return fold_build1 (code, type, new_name);
	  }

	case ARRAY_REF:
	  {
	    tree op00 = TREE_OPERAND (op0, 0);
	    tree op01 = TREE_OPERAND (op0, 1);
	    tree op02 = TREE_OPERAND (op0, 2);
	    tree op03 = TREE_OPERAND (op0, 3);
	    tree base = expand_scalar_variables_expr
	      (TREE_TYPE (op00), op00, TREE_CODE (op00), NULL, bb, scop,
	       map, gsi);
	    tree subscript = expand_scalar_variables_expr
	      (TREE_TYPE (op01), op01, TREE_CODE (op01), NULL, bb, scop,
	       map, gsi);

	    return build4 (ARRAY_REF, type, base, subscript, op02, op03);
	  }

	default:
	  /* The above cases should catch everything.  */
	  gcc_unreachable ();
	}
    }

  if (TREE_CODE_CLASS (code) == tcc_unary)
    {
      tree op0_type = TREE_TYPE (op0);
      enum tree_code op0_code = TREE_CODE (op0);
      tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code,
						    NULL, bb, scop, map, gsi);
  
      return fold_build1 (code, type, op0_expr);
    }

  if (TREE_CODE_CLASS (code) == tcc_binary)
    {
      tree op0_type = TREE_TYPE (op0);
      enum tree_code op0_code = TREE_CODE (op0);
      tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code,
						    NULL, bb, scop, map, gsi);
      tree op1_type = TREE_TYPE (op1);
      enum tree_code op1_code = TREE_CODE (op1);
      tree op1_expr = expand_scalar_variables_expr (op1_type, op1, op1_code,
						    NULL, bb, scop, map, gsi);

      return fold_build2 (code, type, op0_expr, op1_expr);
    }

  if (code == SSA_NAME)
    return expand_scalar_variables_ssa_name (op0, bb, scop, map, gsi);

  gcc_unreachable ();
  return NULL;
}

/* Copies at the beginning of BB all the scalar computations on which
   STMT depends on in the SCOP: these are all the scalar variables used
   in STMT, defined outside BB and still defined in the SCOP, i.e. not a
   parameter of the SCOP.  The expression that is returned contains
   only induction variables from the generated code: MAP contains the
   induction variables renaming mapping, and is used to translate the
   names of induction variables.  */
 
static void
expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop,
			      htab_t map)
{
  ssa_op_iter iter;
  use_operand_p use_p;
  gimple_stmt_iterator gsi = gsi_after_labels (bb);

  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
    {
      tree use = USE_FROM_PTR (use_p);
      tree type = TREE_TYPE (use);
      enum tree_code code = TREE_CODE (use);
      tree use_expr = expand_scalar_variables_expr (type, use, code, NULL, bb,
						    scop, map, &gsi);
      if (use_expr != use)
	{
	  tree new_use =
	    force_gimple_operand_gsi (&gsi, use_expr, true, NULL,
				      true, GSI_NEW_STMT);
	  replace_exp (use_p, new_use);
	}
    }

  update_stmt (stmt);
}

/* Copies at the beginning of BB all the scalar computations on which
   BB depends on in the SCOP: these are all the scalar variables used
   in BB, defined outside BB and still defined in the SCOP, i.e. not a
   parameter of the SCOP.  The expression that is returned contains
   only induction variables from the generated code: MAP contains the
   induction variables renaming mapping, and is used to translate the
   names of induction variables.  */

static void 
expand_scalar_variables (basic_block bb, scop_p scop, htab_t map)
{
  gimple_stmt_iterator gsi;
  
  for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
    {
      gimple stmt = gsi_stmt (gsi);
      expand_scalar_variables_stmt (stmt, bb, scop, map);
      gsi_next (&gsi);
    }
}

/* Rename all the SSA_NAMEs from block BB according to the MAP.  */

static void 
rename_variables (basic_block bb, htab_t map)
{
  gimple_stmt_iterator gsi;
  
  for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    rename_variables_in_stmt (gsi_stmt (gsi), map);
}

/* Remove condition from BB.  */

static void
remove_condition (basic_block bb)
{
  gimple last = last_stmt (bb);

  if (last && gimple_code (last) == GIMPLE_COND)
    {
      gimple_stmt_iterator gsi = gsi_last_bb (bb);
      gsi_remove (&gsi, true);
    }
}

/* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag set.  */

static edge
get_true_edge_from_guard_bb (basic_block bb)
{
  edge e;
  edge_iterator ei;

  FOR_EACH_EDGE (e, ei, bb->succs)
    if (e->flags & EDGE_TRUE_VALUE) 
      return e;

  gcc_unreachable ();
  return NULL;
}

/* Returns the first successor edge of BB with EDGE_TRUE_VALUE flag cleared.  */

static edge
get_false_edge_from_guard_bb (basic_block bb)
{
  edge e;
  edge_iterator ei;

  FOR_EACH_EDGE (e, ei, bb->succs)
    if (!(e->flags & EDGE_TRUE_VALUE)) 
      return e;

  gcc_unreachable ();
  return NULL;
}

/* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction
   variables of the loops around GBB in SCOP, i.e. GBB_LOOPS.
   NEW_NAME is obtained from IVSTACK.  IVSTACK has the same stack
   ordering as GBB_LOOPS.  */

static void
build_iv_mapping (loop_iv_stack ivstack, htab_t map, gbb_p gbb, scop_p scop)
{
  int i;
  name_tree iv;
  PTR *slot;

  for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++)
    {
      struct rename_map_elt tmp;

      if (!flow_bb_inside_loop_p (iv->loop, GBB_BB (gbb)))
	continue;

      tmp.old_name = iv->t;
      slot = htab_find_slot (map, &tmp, INSERT);

      if (!*slot)
	{
	  tree new_name = loop_iv_stack_get_iv (ivstack, 
						gbb_loop_index (gbb, iv->loop));
	  *slot = new_rename_map_elt (iv->t, new_name);
	}
    }
}

/* Register in MAP the tuple (old_name, new_name).  */

static void
register_old_and_new_names (htab_t map, tree old_name, tree new_name)
{
  struct rename_map_elt tmp;
  PTR *slot;

  tmp.old_name = old_name;
  slot = htab_find_slot (map, &tmp, INSERT);

  if (!*slot)
    *slot = new_rename_map_elt (old_name, new_name);
}

/* Create a duplicate of the basic block BB.  NOTE: This does not
   preserve SSA form.  */

static void
graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, htab_t map)
{
  gimple_stmt_iterator gsi, gsi_tgt;

  gsi_tgt = gsi_start_bb (new_bb);
  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      def_operand_p def_p;
      ssa_op_iter op_iter;
      int region;
      gimple stmt = gsi_stmt (gsi);
      gimple copy;

      if (gimple_code (stmt) == GIMPLE_LABEL)
	continue;

      /* Create a new copy of STMT and duplicate STMT's virtual
	 operands.  */
      copy = gimple_copy (stmt);
      gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
      mark_symbols_for_renaming (copy);

      region = lookup_stmt_eh_region (stmt);
      if (region >= 0)
	add_stmt_to_eh_region (copy, region);
      gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);

      /* Create new names for all the definitions created by COPY and
	 add replacement mappings for each new name.  */
      FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_DEF)
	{
	  tree old_name = DEF_FROM_PTR (def_p);
	  tree new_name = create_new_def_for (old_name, copy, def_p);
	  register_old_and_new_names (map, old_name, new_name);
	}
    }
}

/* Records in SCOP_LIVEOUT_RENAMES the names that are live out of
   the SCOP and that appear in the RENAME_MAP.  */

static void
register_scop_liveout_renames (scop_p scop, htab_t rename_map)
{
  int i;
  sese region = SCOP_REGION (scop);

  for (i = 0; i < SESE_NUM_VER (region); i++)
    if (bitmap_bit_p (SESE_LIVEOUT (region), i)
	&& is_gimple_reg (ssa_name (i)))
      {
	tree old_name = ssa_name (i);
	tree new_name = get_new_name_from_old_name (rename_map, old_name);

	register_old_and_new_names (SCOP_LIVEOUT_RENAMES (scop),
				    old_name, new_name);
      }
}

/* 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.  */
 
static edge
copy_bb_and_scalar_dependences (basic_block bb, scop_p scop,
				edge next_e, htab_t map)
{
  basic_block new_bb = split_edge (next_e);

  next_e = single_succ_edge (new_bb);
  graphite_copy_stmts_from_block (bb, new_bb, map);
  remove_condition (new_bb);
  rename_variables (new_bb, map);
  remove_phi_nodes (new_bb);
  expand_scalar_variables (new_bb, scop, map);
  register_scop_liveout_renames (scop, map);

  return next_e;
}

/* Helper function for htab_traverse in insert_loop_close_phis.  */

static int
add_loop_exit_phis (void **slot, void *s)
{
  struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
  tree new_name = entry->new_name;
  basic_block bb = (basic_block) s;
  gimple phi = create_phi_node (new_name, bb);
  tree res = create_new_def_for (gimple_phi_result (phi), phi,
				 gimple_phi_result_ptr (phi));

  add_phi_arg (phi, new_name, single_pred_edge (bb));

  entry->new_name = res;
  *slot = entry;
  return 1;
}

/* Iterate over the SCOP_LIVEOUT_RENAMES (SCOP) and get tuples of the
   form (OLD_NAME, NEW_NAME).  Insert in BB "RES = phi (NEW_NAME)",
   and finally register in SCOP_LIVEOUT_RENAMES (scop) the tuple
   (OLD_NAME, RES).  */

static void
insert_loop_close_phis (scop_p scop, basic_block bb)
{
  update_ssa (TODO_update_ssa);
  htab_traverse (SCOP_LIVEOUT_RENAMES (scop), add_loop_exit_phis, bb);
  update_ssa (TODO_update_ssa);
}

/* Helper structure for htab_traverse in insert_guard_phis.  */

struct igp {
  basic_block bb;
  edge true_edge, false_edge;
  htab_t liveout_before_guard;
};

/* Return the default name that is before the guard.  */

static tree
default_liveout_before_guard (htab_t liveout_before_guard, tree old_name)
{
  tree res = get_new_name_from_old_name (liveout_before_guard, old_name);

  if (res == old_name)
    {
      if (is_gimple_reg (res))
	return fold_convert (TREE_TYPE (res), integer_zero_node);
      return gimple_default_def (cfun, res);
    }

  return res;
}

/* Helper function for htab_traverse in insert_guard_phis.  */

static int
add_guard_exit_phis (void **slot, void *s)
{
  struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
  struct igp *i = (struct igp *) s;
  basic_block bb = i->bb;
  edge true_edge = i->true_edge;
  edge false_edge = i->false_edge;
  tree name1 = entry->new_name;
  tree name2 = default_liveout_before_guard (i->liveout_before_guard,
					     entry->old_name);
  gimple phi = create_phi_node (name1, bb);
  tree res = create_new_def_for (gimple_phi_result (phi), phi,
				 gimple_phi_result_ptr (phi));

  add_phi_arg (phi, name1, true_edge);
  add_phi_arg (phi, name2, false_edge);

  entry->new_name = res;
  *slot = entry;
  return 1;
}

/* Iterate over the SCOP_LIVEOUT_RENAMES (SCOP) and get tuples of the
   form (OLD_NAME, NAME1).  If there is a correspondent tuple of
   OLD_NAME in LIVEOUT_BEFORE_GUARD, i.e. (OLD_NAME, NAME2) then
   insert in BB
   
   | RES = phi (NAME1 (on TRUE_EDGE), NAME2 (on FALSE_EDGE))"

   if there is no tuple for OLD_NAME in LIVEOUT_BEFORE_GUARD, insert

   | RES = phi (NAME1 (on TRUE_EDGE),
   |            DEFAULT_DEFINITION of NAME1 (on FALSE_EDGE))".

   Finally register in SCOP_LIVEOUT_RENAMES (scop) the tuple
   (OLD_NAME, RES).  */

static void
insert_guard_phis (scop_p scop, basic_block bb, edge true_edge,
		   edge false_edge, htab_t liveout_before_guard)
{
  struct igp i;
  i.bb = bb;
  i.true_edge = true_edge;
  i.false_edge = false_edge;
  i.liveout_before_guard = liveout_before_guard;

  update_ssa (TODO_update_ssa);
  htab_traverse (SCOP_LIVEOUT_RENAMES (scop), add_guard_exit_phis, &i);
  update_ssa (TODO_update_ssa);
}

/* Helper function for htab_traverse.  */

static int
copy_renames (void **slot, void *s)
{
  struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
  htab_t res = (htab_t) s;
  tree old_name = entry->old_name;
  tree new_name = entry->new_name;
  struct rename_map_elt tmp;
  PTR *x;

  tmp.old_name = old_name;
  x = htab_find_slot (res, &tmp, INSERT);

  if (!*x)
    *x = new_rename_map_elt (old_name, new_name);

  return 1;
}

/* Translates a CLAST statement STMT to GCC representation in the
   context of a SCOP.

   - NEXT_E is the edge where new generated code should be attached.
   - CONTEXT_LOOP is the loop in which the generated code will be placed
     (might be NULL).  
   - IVSTACK contains the surrounding loops around the statement to be
     translated.
*/

static edge
translate_clast (scop_p scop, struct loop *context_loop,
		 struct clast_stmt *stmt, edge next_e, loop_iv_stack ivstack)
{
  if (!stmt)
    return next_e;

  if (CLAST_STMT_IS_A (stmt, stmt_root))
    return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);

  if (CLAST_STMT_IS_A (stmt, stmt_user))
    {
      htab_t map;
      CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
      graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);

      if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
	return next_e;

      map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free);
      loop_iv_stack_patch_for_consts (ivstack, (struct clast_user_stmt *) stmt);
      build_iv_mapping (ivstack, map, gbb, scop);
      next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), scop,
					       next_e, map);
      htab_delete (map);
      loop_iv_stack_remove_constants (ivstack);
      update_ssa (TODO_update_ssa);
      recompute_all_dominators ();
      graphite_verify ();
      return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
    }

  if (CLAST_STMT_IS_A (stmt, stmt_for))
    {
      struct loop *loop
	= graphite_create_new_loop (scop, next_e, (struct clast_for *) stmt,
				    ivstack, context_loop ? context_loop
				    : get_loop (0));
      edge last_e = single_exit (loop);

      next_e = translate_clast (scop, loop, ((struct clast_for *) stmt)->body,
				single_pred_edge (loop->latch), ivstack);
      redirect_edge_succ_nodup (next_e, loop->latch);

      set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
      loop_iv_stack_pop (ivstack);
      last_e = single_succ_edge (split_edge (last_e));
      insert_loop_close_phis (scop, last_e->src);

      recompute_all_dominators ();
      graphite_verify ();
      return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
    }

  if (CLAST_STMT_IS_A (stmt, stmt_guard))
    {
      htab_t liveout_before_guard = htab_create (10, rename_map_elt_info,
						 eq_rename_map_elts, free);
      edge last_e = graphite_create_new_guard (scop, next_e,
					       ((struct clast_guard *) stmt),
					       ivstack);
      edge true_e = get_true_edge_from_guard_bb (next_e->dest);
      edge false_e = get_false_edge_from_guard_bb (next_e->dest);
      edge exit_true_e = single_succ_edge (true_e->dest);
      edge exit_false_e = single_succ_edge (false_e->dest);

      htab_traverse (SCOP_LIVEOUT_RENAMES (scop), copy_renames,
		     liveout_before_guard);

      next_e = translate_clast (scop, context_loop, 
				((struct clast_guard *) stmt)->then,
				true_e, ivstack);
      insert_guard_phis (scop, last_e->src, exit_true_e, exit_false_e,
			 liveout_before_guard);
      htab_delete (liveout_before_guard);
      recompute_all_dominators ();
      graphite_verify ();

      return translate_clast (scop, context_loop, stmt->next, last_e, ivstack);
    }

  if (CLAST_STMT_IS_A (stmt, stmt_block))
    {
      next_e = translate_clast (scop, context_loop,
				((struct clast_block *) stmt)->body,
				next_e, ivstack);
      recompute_all_dominators ();
      graphite_verify ();
      return translate_clast (scop, context_loop, stmt->next, next_e, ivstack);
    }

  gcc_unreachable ();
}

/* Free the SCATTERING domain list.  */

static void
free_scattering (CloogDomainList *scattering)
{
  while (scattering)
    {
      CloogDomain *dom = cloog_domain (scattering);
      CloogDomainList *next = cloog_next_domain (scattering);

      cloog_domain_free (dom);
      free (scattering);
      scattering = next;
    }
}

/* Build cloog program for SCoP.  */

static void
build_cloog_prog (scop_p scop)
{
  int i;
  int max_nb_loops = scop_max_loop_depth (scop);
  graphite_bb_p gbb;
  CloogLoop *loop_list = NULL;
  CloogBlockList *block_list = NULL;
  CloogDomainList *scattering = NULL;
  CloogProgram *prog = SCOP_PROG (scop);
  int nbs = 2 * max_nb_loops + 1;
  int *scaldims = (int *) xmalloc (nbs * (sizeof (int)));

  cloog_program_set_nb_scattdims (prog, nbs);
  initialize_cloog_names (scop);

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
    {
      /* Build new block.  */
      CloogMatrix *domain = GBB_DOMAIN (gbb);
      CloogStatement *stmt = cloog_statement_alloc (GBB_BB (gbb)->index);
      CloogBlock *block = cloog_block_alloc (stmt, 0, NULL,
					     nb_loops_around_gb (gbb));
      cloog_statement_set_usr (stmt, gbb);

      /* Add empty domain to all bbs, which do not yet have a domain, as they
         are not part of any loop.  */
      if (domain == NULL)
      	{
          domain = cloog_matrix_alloc (0, scop_nb_params (scop) + 2);
          GBB_DOMAIN (gbb) = domain;
	}

      /* Build loop list.  */
      {
        CloogLoop *new_loop_list = cloog_loop_malloc ();
        cloog_loop_set_next (new_loop_list, loop_list);
        cloog_loop_set_domain (new_loop_list,
			       cloog_domain_matrix2domain (domain));
        cloog_loop_set_block (new_loop_list, block);
        loop_list = new_loop_list;
      }

      /* Build block list.  */
      {
        CloogBlockList *new_block_list = cloog_block_list_malloc ();

        cloog_block_list_set_next (new_block_list, block_list);
        cloog_block_list_set_block (new_block_list, block);
        block_list = new_block_list;
      }

      /* Build scattering list.  */
      {
        /* XXX: Replace with cloog_domain_list_alloc(), when available.  */
        CloogDomainList *new_scattering
	  = (CloogDomainList *) xmalloc (sizeof (CloogDomainList));
        CloogMatrix *scat_mat = schedule_to_scattering (gbb, nbs);

        cloog_set_next_domain (new_scattering, scattering);
        cloog_set_domain (new_scattering,
			  cloog_domain_matrix2domain (scat_mat));
        scattering = new_scattering;
        cloog_matrix_free (scat_mat);
      }
    }

  cloog_program_set_loop (prog, loop_list);
  cloog_program_set_blocklist (prog, block_list);

  for (i = 0; i < nbs; i++)
    scaldims[i] = 0 ;

  cloog_program_set_scaldims (prog, scaldims);

  /* Extract scalar dimensions to simplify the code generation problem.  */
  cloog_program_extract_scalars (prog, scattering);

  /* Apply scattering.  */
  cloog_program_scatter (prog, scattering);
  free_scattering (scattering);

  /* Iterators corresponding to scalar dimensions have to be extracted.  */
  cloog_names_scalarize (cloog_program_names (prog), nbs,
			 cloog_program_scaldims (prog));
  
  /* Free blocklist.  */
  {
    CloogBlockList *next = cloog_program_blocklist (prog);
	
    while (next)
      {
        CloogBlockList *toDelete = next;
        next = cloog_block_list_next (next);
        cloog_block_list_set_next (toDelete, NULL);
        cloog_block_list_set_block (toDelete, NULL);
        cloog_block_list_free (toDelete);
      }
    cloog_program_set_blocklist (prog, NULL);
  }
}

/* Return the options that will be used in GLOOG.  */

static CloogOptions *
set_cloog_options (void)
{
  CloogOptions *options = cloog_options_malloc ();

  /* Change cloog output language to C.  If we do use FORTRAN instead, cloog
     will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
     we pass an incomplete program to cloog.  */
  options->language = LANGUAGE_C;

  /* Enable complex equality spreading: removes dummy statements
     (assignments) in the generated code which repeats the
     substitution equations for statements.  This is useless for
     GLooG.  */
  options->esp = 1;

  /* Enable C pretty-printing mode: normalizes the substitution
     equations for statements.  */
  options->cpp = 1;

  /* Allow cloog to build strides with a stride width different to one.
     This example has stride = 4:

     for (i = 0; i < 20; i += 4)
       A  */
  options->strides = 1;

  /* Disable optimizations and make cloog generate source code closer to the
     input.  This is useful for debugging,  but later we want the optimized
     code.

     XXX: We can not disable optimizations, as loop blocking is not working
     without them.  */
  if (0)
    {
      options->f = -1;
      options->l = INT_MAX;
    }

  return options;
}

/* Prints STMT to STDERR.  */

void
debug_clast_stmt (struct clast_stmt *stmt)
{
  CloogOptions *options = set_cloog_options ();

  pprint (stderr, stmt, 0, options);
}

/* Find the right transform for the SCOP, and return a Cloog AST
   representing the new form of the program.  */

static struct clast_stmt *
find_transform (scop_p scop)
{
  struct clast_stmt *stmt;
  CloogOptions *options = set_cloog_options ();

  /* Connect new cloog prog generation to graphite.  */
  build_cloog_prog (scop);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Cloog Input [\n");
      cloog_program_print (dump_file, SCOP_PROG(scop));
      fprintf (dump_file, "]\n");
    }

  SCOP_PROG (scop) = cloog_program_generate (SCOP_PROG (scop), options);
  stmt = cloog_clast_create (SCOP_PROG (scop), options);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Cloog Output[\n");
      pprint (dump_file, stmt, 0, options);
      cloog_program_dump_cloog (dump_file, SCOP_PROG (scop));
      fprintf (dump_file, "]\n");
    }

  cloog_options_free (options);
  return stmt;
}

/* Remove from the CFG the REGION.  */

static inline void
remove_sese_region (sese region)
{
  VEC (basic_block, heap) *bbs = NULL;
  basic_block entry_bb = SESE_ENTRY (region)->dest;
  basic_block exit_bb = SESE_EXIT (region)->dest;
  basic_block bb;
  int i;

  VEC_safe_push (basic_block, heap, bbs, entry_bb);
  gather_blocks_in_sese_region (entry_bb, exit_bb, &bbs);

  for (i = 0; VEC_iterate (basic_block, bbs, i, bb); i++)
    delete_basic_block (bb);

  VEC_free (basic_block, heap, bbs);
}

typedef struct ifsese {
  sese region;
  sese true_region;
  sese false_region;
} *ifsese;

static inline edge
if_region_entry (ifsese if_region)
{
  return SESE_ENTRY (if_region->region);
}

static inline edge
if_region_exit (ifsese if_region)
{
  return SESE_EXIT (if_region->region);
}

static inline basic_block
if_region_get_condition_block (ifsese if_region)
{
  return if_region_entry (if_region)->dest;
}

static inline void
if_region_set_false_region (ifsese if_region, sese region)
{
  basic_block condition = if_region_get_condition_block (if_region);
  edge false_edge = get_false_edge_from_guard_bb (condition);
  basic_block dummy = false_edge->dest;
  edge entry_region = SESE_ENTRY (region);
  edge exit_region = SESE_EXIT (region);
  basic_block before_region = entry_region->src;
  basic_block last_in_region = exit_region->src;
  void **slot = htab_find_slot_with_hash (current_loops->exits, exit_region,
					  htab_hash_pointer (exit_region),
					  NO_INSERT);

  entry_region->flags = false_edge->flags;
  false_edge->flags = exit_region->flags;

  redirect_edge_pred (entry_region, condition);
  redirect_edge_pred (exit_region, before_region);
  redirect_edge_pred (false_edge, last_in_region);
  redirect_edge_succ (false_edge, single_succ (dummy));
  delete_basic_block (dummy);

  exit_region->flags = EDGE_FALLTHRU;
  recompute_all_dominators ();

  SESE_EXIT (region) = false_edge;
  if_region->false_region = region;

  if (slot)
    {
      struct loop_exit *loop_exit = GGC_CNEW (struct loop_exit);

      memcpy (loop_exit, *((struct loop_exit **) slot), sizeof (struct loop_exit));
      htab_clear_slot (current_loops->exits, slot);

      slot = htab_find_slot_with_hash (current_loops->exits, false_edge,
				       htab_hash_pointer (false_edge),
				       INSERT);
      loop_exit->e = false_edge;
      *slot = loop_exit;
      false_edge->src->loop_father->exits->next = loop_exit;
    }
}

static ifsese
create_if_region_on_edge (edge entry, tree condition)
{
  edge e;
  edge_iterator ei;
  sese sese_region = GGC_NEW (struct sese);
  sese true_region = GGC_NEW (struct sese);
  sese false_region = GGC_NEW (struct sese);
  ifsese if_region = GGC_NEW (struct ifsese);
  edge exit = create_empty_if_region_on_edge (entry, condition);

  if_region->region = sese_region;
  if_region->region->entry = entry;
  if_region->region->exit = exit;

  FOR_EACH_EDGE (e, ei, entry->dest->succs)
    {
      if (e->flags & EDGE_TRUE_VALUE)
	{
	  true_region->entry = e;
	  true_region->exit = single_succ_edge (e->dest);
	  if_region->true_region = true_region;
	}
      else if (e->flags & EDGE_FALSE_VALUE)
	{
	  false_region->entry = e;
	  false_region->exit = single_succ_edge (e->dest);
	  if_region->false_region = false_region;
	}
    }

  return if_region;
}

/* Moves REGION in a condition expression:
   | if (1)
   |   ;
   | else
   |   REGION;
*/

static ifsese
move_sese_in_condition (sese region)
{
  basic_block pred_block = split_edge (SESE_ENTRY (region));
  ifsese if_region = NULL;

  SESE_ENTRY (region) = single_succ_edge (pred_block);
  if_region = create_if_region_on_edge (single_pred_edge (pred_block), integer_one_node);
  if_region_set_false_region (if_region, region);

  return if_region;
}

/* Add exit phis for USE on EXIT.  */

static void
scop_add_exit_phis_edge (basic_block exit, tree use, edge false_e, edge true_e)
{
  gimple phi = create_phi_node (use, exit);

  create_new_def_for (gimple_phi_result (phi), phi,
		      gimple_phi_result_ptr (phi));
  add_phi_arg (phi, use, false_e);
  add_phi_arg (phi, use, true_e);
}

/* Add phi nodes for VAR that is used in LIVEIN.  Phi nodes are
   inserted in block BB.  */

static void
scop_add_exit_phis_var (basic_block bb, tree var, bitmap livein,
			edge false_e, edge true_e)
{
  bitmap def;
  basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (var));

  if (is_gimple_reg (var))
    bitmap_clear_bit (livein, def_bb->index);
  else
    bitmap_set_bit (livein, def_bb->index);

  def = BITMAP_ALLOC (NULL);
  bitmap_set_bit (def, def_bb->index);
  compute_global_livein (livein, def);
  BITMAP_FREE (def);

  scop_add_exit_phis_edge (bb, var, false_e, true_e);
}

/* Insert in the block BB phi nodes for variables defined in REGION
   and used outside the REGION.  The code generation moves REGION in
   the else clause of an "if (1)" and generates code in the then
   clause that is at this point empty:

   | if (1)
   |   empty;
   | else
   |   REGION;
*/

static void
scop_insert_phis_for_liveouts (sese region, basic_block bb,
			       edge false_e, edge true_e)
{
  unsigned i;
  bitmap_iterator bi;

  update_ssa (TODO_update_ssa);

  EXECUTE_IF_SET_IN_BITMAP (SESE_LIVEOUT (region), 0, i, bi)
    scop_add_exit_phis_var (bb, ssa_name (i), SESE_LIVEIN_VER (region, i),
			    false_e, true_e);

  update_ssa (TODO_update_ssa);
}

/* Get the definition of NAME before the SCOP.  Keep track of the
   basic blocks that have been VISITED in a bitmap.  */

static tree
get_vdef_before_scop (scop_p scop, tree name, sbitmap visited)
{
  unsigned i;
  gimple def_stmt = SSA_NAME_DEF_STMT (name);
  basic_block def_bb = gimple_bb (def_stmt);

  if (!def_bb
      || !bb_in_sese_p (def_bb, SCOP_REGION (scop)))
    return name;

  if (TEST_BIT (visited, def_bb->index))
    return NULL_TREE;

  SET_BIT (visited, def_bb->index);

  switch (gimple_code (def_stmt))
    {
    case GIMPLE_PHI:
      for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
	{
	  tree arg = gimple_phi_arg_def (def_stmt, i);
	  tree res = get_vdef_before_scop (scop, arg, visited);
	  if (res)
	    return res;
	}
      return NULL_TREE;

    default:
      return NULL_TREE;
    }
}

/* Adjust a virtual phi node PHI that is placed at the end of the
   generated code for SCOP:

   | if (1)
   |   generated code from REGION;
   | else
   |   REGION;

   The FALSE_E edge comes from the original code, TRUE_E edge comes
   from the code generated for the SCOP.  */

static void
scop_adjust_vphi (scop_p scop, gimple phi, edge true_e)
{
  unsigned i;

  gcc_assert (gimple_phi_num_args (phi) == 2);

  for (i = 0; i < gimple_phi_num_args (phi); i++)
    if (gimple_phi_arg_edge (phi, i) == true_e)
      {
	tree true_arg, false_arg, before_scop_arg;
	sbitmap visited;

	true_arg = gimple_phi_arg_def (phi, i);
	if (!SSA_NAME_IS_DEFAULT_DEF (true_arg))
	  return;

	false_arg = gimple_phi_arg_def (phi, i == 0 ? 1 : 0);
	if (SSA_NAME_IS_DEFAULT_DEF (false_arg))
	  return;

	visited = sbitmap_alloc (last_basic_block);
	sbitmap_zero (visited);
	before_scop_arg = get_vdef_before_scop (scop, false_arg, visited);
	gcc_assert (before_scop_arg != NULL_TREE);
	SET_PHI_ARG_DEF (phi, i, before_scop_arg);
	sbitmap_free (visited);
      }
}

/* Adjusts the phi nodes in the block BB for variables defined in
   SCOP_REGION and used outside the SCOP_REGION.  The code generation
   moves SCOP_REGION in the else clause of an "if (1)" and generates
   code in the then clause:

   | if (1)
   |   generated code from REGION;
   | else
   |   REGION;

   To adjust the phi nodes after the condition, SCOP_LIVEOUT_RENAMES
   hash table is used: this stores for a name that is part of the
   LIVEOUT of SCOP_REGION its new name in the generated code.  */

static void
scop_adjust_phis_for_liveouts (scop_p scop, basic_block bb, edge false_e,
			       edge true_e)
{
  gimple_stmt_iterator si;

  for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
    {
      unsigned i;
      unsigned false_i = 0;
      gimple phi = gsi_stmt (si);

      if (!is_gimple_reg (PHI_RESULT (phi)))
	{
	  scop_adjust_vphi (scop, phi, true_e);
	  continue;
	}

      for (i = 0; i < gimple_phi_num_args (phi); i++)
	if (gimple_phi_arg_edge (phi, i) == false_e)
	  {
	    false_i = i;
	    break;
	  }

      for (i = 0; i < gimple_phi_num_args (phi); i++)
	if (gimple_phi_arg_edge (phi, i) == true_e)
	  {
	    tree old_name = gimple_phi_arg_def (phi, false_i);
	    tree new_name = get_new_name_from_old_name
	      (SCOP_LIVEOUT_RENAMES (scop), old_name);

	    gcc_assert (old_name != new_name);
	    SET_PHI_ARG_DEF (phi, i, new_name);
	  }
    }
}

/* Returns the first cloog name used in EXPR.  */

static const char *
find_cloog_iv_in_expr (struct clast_expr *expr)
{
  struct clast_term *term = (struct clast_term *) expr;

  if (expr->type == expr_term
      && !term->var)
    return NULL;

  if (expr->type == expr_term)
    return term->var;

  if (expr->type == expr_red)
    {
      int i;
      struct clast_reduction *red = (struct clast_reduction *) expr;

      for (i = 0; i < red->n; i++)
	{
	  const char *res = find_cloog_iv_in_expr ((red)->elts[i]);

	  if (res)
	    return res;
	}
    }

  return NULL;
}

/* Build for a clast_user_stmt USER_STMT a map between the CLAST
   induction variables and the corresponding GCC old induction
   variables.  This information is stored on each GRAPHITE_BB.  */

static void
compute_cloog_iv_types_1 (graphite_bb_p gbb,
			  struct clast_user_stmt *user_stmt)
{
  struct clast_stmt *t;
  int index = 0;

  for (t = user_stmt->substitutions; t; t = t->next, index++)
    {
      PTR *slot;
      struct ivtype_map_elt tmp;
      struct clast_expr *expr = (struct clast_expr *) 
	((struct clast_assignment *)t)->RHS;

      /* Create an entry (clast_var, type).  */
      tmp.cloog_iv = find_cloog_iv_in_expr (expr);
      if (!tmp.cloog_iv)
	continue;

      slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, INSERT);

      if (!*slot)
	{
	  loop_p loop = gbb_loop_at_index (gbb, index);
	  tree oldiv = oldiv_for_loop (GBB_SCOP (gbb), loop);
	  tree type = oldiv ? TREE_TYPE (oldiv) : integer_type_node;
	  *slot = new_ivtype_map_elt (tmp.cloog_iv, type);
	}
    }
}

/* Walk the CLAST tree starting from STMT and build for each
   clast_user_stmt a map between the CLAST induction variables and the
   corresponding GCC old induction variables.  This information is
   stored on each GRAPHITE_BB.  */

static void
compute_cloog_iv_types (struct clast_stmt *stmt)
{
  if (!stmt)
    return;

  if (CLAST_STMT_IS_A (stmt, stmt_root))
    goto next;

  if (CLAST_STMT_IS_A (stmt, stmt_user))
    {
      CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
      graphite_bb_p gbb = (graphite_bb_p) cloog_statement_usr (cs);
      GBB_CLOOG_IV_TYPES (gbb) = htab_create (10, ivtype_map_elt_info,
					      eq_ivtype_map_elts, free);
      compute_cloog_iv_types_1 (gbb, (struct clast_user_stmt *) stmt);
      goto next;
    }

  if (CLAST_STMT_IS_A (stmt, stmt_for))
    {
      struct clast_stmt *s = ((struct clast_for *) stmt)->body;
      compute_cloog_iv_types (s);
      goto next;
    }

  if (CLAST_STMT_IS_A (stmt, stmt_guard))
    {
      struct clast_stmt *s = ((struct clast_guard *) stmt)->then;
      compute_cloog_iv_types (s);
      goto next;
    }

  if (CLAST_STMT_IS_A (stmt, stmt_block))
    {
      struct clast_stmt *s = ((struct clast_block *) stmt)->body;
      compute_cloog_iv_types (s);
      goto next;
    }

  gcc_unreachable ();

 next:
  compute_cloog_iv_types (stmt->next);
}

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

static bool
gloog (scop_p scop, struct clast_stmt *stmt)
{
  edge new_scop_exit_edge = NULL;
  VEC (iv_stack_entry_p, heap) *ivstack = VEC_alloc (iv_stack_entry_p, heap,
						     10);
  loop_p context_loop;
  ifsese if_region = NULL;

  recompute_all_dominators ();
  graphite_verify ();
  if_region = move_sese_in_condition (SCOP_REGION (scop));
  sese_build_livein_liveouts (SCOP_REGION (scop));
  scop_insert_phis_for_liveouts (SCOP_REGION (scop),
				 if_region->region->exit->src,
				 if_region->false_region->exit,
				 if_region->true_region->exit);
  recompute_all_dominators ();
  graphite_verify ();
  context_loop = SESE_ENTRY (SCOP_REGION (scop))->src->loop_father;
  compute_cloog_iv_types (stmt);

  new_scop_exit_edge = translate_clast (scop, context_loop, stmt,
					if_region->true_region->entry,
					&ivstack);
  free_loop_iv_stack (&ivstack);
  cloog_clast_free (stmt);

  graphite_verify ();
  scop_adjust_phis_for_liveouts (scop,
				 if_region->region->exit->src,
				 if_region->false_region->exit,
				 if_region->true_region->exit);

  recompute_all_dominators ();
  graphite_verify ();
  return true;
}

/* Returns the number of data references in SCOP.  */

static int
nb_data_refs_in_scop (scop_p scop)
{
  int i;
  graphite_bb_p gbb;
  int res = 0;

  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gbb); i++)
    res += VEC_length (data_reference_p, GBB_DATA_REFS (gbb));

  return res;
}

/* Move the loop at index LOOP and insert it before index NEW_LOOP_POS.
   This transformartion is only valid, if the loop nest between i and k is
   perfectly nested. Therefore we do not need to change the static schedule.

   Example:

   for (i = 0; i < 50; i++)
     for (j ...)
       for (k = 5; k < 100; k++)
         A

   To move k before i use:

   graphite_trans_bb_move_loop (A, 2, 0)

   for (k = 5; k < 100; k++)
     for (i = 0; i < 50; i++)
       for (j ...)
         A

   And to move k back:

   graphite_trans_bb_move_loop (A, 0, 2)

   This function does not check the validity of interchanging loops.
   This should be checked before calling this function.  */

static void
graphite_trans_bb_move_loop (graphite_bb_p gb, int loop,
			     int new_loop_pos)
{
  CloogMatrix *domain = GBB_DOMAIN (gb);
  int row, j;
  loop_p tmp_loop_p;

  gcc_assert (loop < gbb_nb_loops (gb)
	      && new_loop_pos < gbb_nb_loops (gb));

  /* Update LOOPS vector.  */
  tmp_loop_p = VEC_index (loop_p, GBB_LOOPS (gb), loop);
  VEC_ordered_remove (loop_p, GBB_LOOPS (gb), loop);
  VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), new_loop_pos, tmp_loop_p);

  /* Move the domain columns.  */
  if (loop < new_loop_pos)
    for (row = 0; row < domain->NbRows; row++)
      {
        Value tmp;
        value_init (tmp);
        value_assign (tmp, domain->p[row][loop + 1]);
   
        for (j = loop ; j < new_loop_pos - 1; j++)
          value_assign (domain->p[row][j + 1], domain->p[row][j + 2]);

        value_assign (domain->p[row][new_loop_pos], tmp);
        value_clear (tmp);
      }
  else
    for (row = 0; row < domain->NbRows; row++)
      {
        Value tmp;
        value_init (tmp);
        value_assign (tmp, domain->p[row][loop + 1]);

        for (j = loop ; j > new_loop_pos; j--)
          value_assign (domain->p[row][j + 1], domain->p[row][j]);
     
        value_assign (domain->p[row][new_loop_pos + 1], tmp);
        value_clear (tmp);
      }
}

/* Get the index of the column representing constants in the DOMAIN
   matrix.  */

static int
const_column_index (CloogMatrix *domain)
{
  return domain->NbColumns - 1;
}


/* Get the first index that is positive or negative, determined
   following the value of POSITIVE, in matrix DOMAIN in COLUMN.  */

static int
get_first_matching_sign_row_index (CloogMatrix *domain, int column,
				   bool positive)
{
  int row;

  for (row = 0; row < domain->NbRows; row++)
    {
      int val = value_get_si (domain->p[row][column]);

      if (val > 0 && positive)
	return row;

      else if (val < 0 && !positive)
	return row;
    }

  gcc_unreachable ();
}

/* Get the lower bound of COLUMN in matrix DOMAIN.  */

static int
get_lower_bound_row (CloogMatrix *domain, int column)
{
  return get_first_matching_sign_row_index (domain, column, true);
}

/* Get the upper bound of COLUMN in matrix DOMAIN.  */

static int
get_upper_bound_row (CloogMatrix *domain, int column)
{
  return get_first_matching_sign_row_index (domain, column, false);
}

/* Copies the OLD_ROW constraint from OLD_DOMAIN to the NEW_DOMAIN at
   row NEW_ROW.  */

static void
copy_constraint (CloogMatrix *old_domain, CloogMatrix *new_domain,
		 int old_row, int new_row)
{
  int i;

  gcc_assert (old_domain->NbColumns == new_domain->NbColumns
	      && old_row < old_domain->NbRows
	      && new_row < new_domain->NbRows);

  for (i = 0; i < old_domain->NbColumns; i++)
    value_assign (new_domain->p[new_row][i], old_domain->p[old_row][i]);
}

/* Swap coefficients of variables X and Y on row R.   */

static void
swap_constraint_variables (CloogMatrix *domain,
			   int r, int x, int y)
{
  value_swap (domain->p[r][x], domain->p[r][y]);
}

/* Scale by X the coefficient C of constraint at row R in DOMAIN.  */

static void
scale_constraint_variable (CloogMatrix *domain,
			   int r, int c, int x)
{
  Value strip_size_value;
  value_init (strip_size_value);
  value_set_si (strip_size_value, x);
  value_multiply (domain->p[r][c], domain->p[r][c], strip_size_value);
  value_clear (strip_size_value);
}

/* Strip mines the loop of BB at the position LOOP_DEPTH with STRIDE.
   Always valid, but not always a performance improvement.  */
  
static void
graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride)
{
  int row, col;

  CloogMatrix *domain = GBB_DOMAIN (gb);
  CloogMatrix *new_domain = cloog_matrix_alloc (domain->NbRows + 3,
                                                domain->NbColumns + 1);   

  int col_loop_old = loop_depth + 2; 
  int col_loop_strip = col_loop_old - 1;

  gcc_assert (loop_depth <= gbb_nb_loops (gb) - 1);

  VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), loop_depth, NULL);

  GBB_DOMAIN (gb) = new_domain;

  for (row = 0; row < domain->NbRows; row++)
    for (col = 0; col < domain->NbColumns; col++)
      if (col <= loop_depth)
	value_assign (new_domain->p[row][col], domain->p[row][col]);
      else
	value_assign (new_domain->p[row][col + 1], domain->p[row][col]);

  row = domain->NbRows;

  /* Lower bound of the outer stripped loop.  */
  copy_constraint (new_domain, new_domain,
		   get_lower_bound_row (new_domain, col_loop_old), row);
  swap_constraint_variables (new_domain, row, col_loop_old, col_loop_strip);
  row++;

  /* Upper bound of the outer stripped loop.  */
  copy_constraint (new_domain, new_domain,
		   get_upper_bound_row (new_domain, col_loop_old), row);
  swap_constraint_variables (new_domain, row, col_loop_old, col_loop_strip);
  scale_constraint_variable (new_domain, row, col_loop_strip, stride);
  row++;

  /* Lower bound of a tile starts at "stride * outer_iv".  */
  row = get_lower_bound_row (new_domain, col_loop_old);
  value_set_si (new_domain->p[row][0], 1);
  value_set_si (new_domain->p[row][const_column_index (new_domain)], 0);
  value_set_si (new_domain->p[row][col_loop_old], 1);
  value_set_si (new_domain->p[row][col_loop_strip], -1 * stride);

  /* Upper bound of a tile stops at "stride * outer_iv + stride - 1",
     or at the old upper bound that is not modified.  */
  row = new_domain->NbRows - 1;
  value_set_si (new_domain->p[row][0], 1);
  value_set_si (new_domain->p[row][col_loop_old], -1);
  value_set_si (new_domain->p[row][col_loop_strip], stride);
  value_set_si (new_domain->p[row][const_column_index (new_domain)],
		stride - 1);

  cloog_matrix_free (domain);

  /* Update static schedule.  */
  {
    int i;
    int nb_loops = gbb_nb_loops (gb);
    lambda_vector new_schedule = lambda_vector_new (nb_loops + 1);

    for (i = 0; i <= loop_depth; i++)
      new_schedule[i] = GBB_STATIC_SCHEDULE (gb)[i];  

    for (i = loop_depth + 1; i <= nb_loops - 2; i++)
      new_schedule[i + 2] = GBB_STATIC_SCHEDULE (gb)[i];  

    GBB_STATIC_SCHEDULE (gb) = new_schedule;
  }
}

/* Returns true when the strip mining of LOOP_INDEX by STRIDE is
   profitable or undecidable.  GB is the statement around which the
   loops will be strip mined.  */

static bool
strip_mine_profitable_p (graphite_bb_p gb, int stride,
			 int loop_index)
{
  bool res = true;
  edge exit = NULL;
  tree niter;
  loop_p loop;
  long niter_val;

  loop = VEC_index (loop_p, GBB_LOOPS (gb), loop_index);
  exit = single_exit (loop);

  niter = find_loop_niter (loop, &exit);
  if (niter == chrec_dont_know 
      || TREE_CODE (niter) != INTEGER_CST)
    return true;
  
  niter_val = int_cst_value (niter);

  if (niter_val < stride)
    {
      res = false;
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "\nStrip Mining is not profitable for loop %d:",
		   loop->num);
	  fprintf (dump_file, "number of iterations is too low.\n");
	}
    }
  
  return res;
}
 
/* Determines when the interchange of LOOP_A and LOOP_B belonging to
   SCOP is legal.  DEPTH is the number of loops around.  */

static bool
is_interchange_valid (scop_p scop, int loop_a, int loop_b, int depth)
{
  bool res;
  VEC (ddr_p, heap) *dependence_relations;
  VEC (data_reference_p, heap) *datarefs;

  struct loop *nest = VEC_index (loop_p, SCOP_LOOP_NEST (scop), loop_a);
  lambda_trans_matrix trans;

  gcc_assert (loop_a < loop_b);

  dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
  datarefs = VEC_alloc (data_reference_p, heap, 10);

  if (!compute_data_dependences_for_loop (nest, true, &datarefs,
					  &dependence_relations))
    return false;

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_ddrs (dump_file, dependence_relations);

  trans = lambda_trans_matrix_new (depth, depth);
  lambda_matrix_id (LTM_MATRIX (trans), depth);

  lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a);

  if (!lambda_transform_legal_p (trans, depth, dependence_relations))
    {
      lambda_matrix_row_exchange (LTM_MATRIX (trans), 0, loop_b - loop_a);
      res = false;
    }
  else
    res = true;

  free_dependence_relations (dependence_relations);
  free_data_refs (datarefs);
  return res;
}

/* Loop block the LOOPS innermost loops of GB with stride size STRIDE. 

   Example

   for (i = 0; i <= 50; i++=4) 
     for (k = 0; k <= 100; k++=4) 
       for (l = 0; l <= 200; l++=4) 
         A

   To strip mine the two inner most loops with stride = 4 call:

   graphite_trans_bb_block (A, 4, 2) 

   for (i = 0; i <= 50; i++) 
     for (kk = 0; kk <= 100; kk+=4) 
       for (ll = 0; ll <= 200; ll+=4) 
         for (k = kk; k <= min (100, kk + 3); k++) 
           for (l = ll; l <= min (200, ll + 3); l++) 
             A
*/

static bool
graphite_trans_bb_block (graphite_bb_p gb, int stride, int loops)
{
  int i, j;
  int nb_loops = gbb_nb_loops (gb);
  int start = nb_loops - loops;
  scop_p scop = GBB_SCOP (gb);

  gcc_assert (scop_contains_loop (scop, gbb_loop (gb)));

  for (i = start ; i < nb_loops; i++)
    for (j = i + 1; j < nb_loops; j++)
      if (!is_interchange_valid (scop, i, j, nb_loops))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file,
		     "\nInterchange not valid for loops %d and %d:\n", i, j);
	  return false;
	}
      else if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "\nInterchange valid for loops %d and %d:\n", i, j);

  /* Check if strip mining is profitable for every loop.  */
  for (i = 0; i < nb_loops - start; i++)
    if (!strip_mine_profitable_p (gb, stride, start + i))
      return false;

  /* Strip mine loops.  */
  for (i = 0; i < nb_loops - start; i++)
    graphite_trans_bb_strip_mine (gb, start + 2 * i, stride);

  /* Interchange loops.  */
  for (i = 1; i < nb_loops - start; i++)
    graphite_trans_bb_move_loop (gb, start + 2 * i, start + i);

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\nLoops containing BB %d will be loop blocked.\n",
	     GBB_BB (gb)->index);

  return true;
}

/* Loop block LOOPS innermost loops of a loop nest.  BBS represent the
   basic blocks that belong to the loop nest to be blocked.  */

static bool
graphite_trans_loop_block (VEC (graphite_bb_p, heap) *bbs, int loops)
{
  graphite_bb_p gb;
  int i;
  bool transform_done = false;

  /* TODO: - Calculate the stride size automatically.  */
  int stride_size = 51;

  for (i = 0; VEC_iterate (graphite_bb_p, bbs, i, gb); i++)
    transform_done |= graphite_trans_bb_block (gb, stride_size, loops);

  return transform_done;
}

/* Loop block all basic blocks of SCOP.  Return false when the
   transform is not performed.  */

static bool
graphite_trans_scop_block (scop_p scop)
{
  graphite_bb_p gb;
  int i, j;
  int last_nb_loops;
  int nb_loops;
  bool perfect = true;
  bool transform_done = false;

  VEC (graphite_bb_p, heap) *bbs = VEC_alloc (graphite_bb_p, heap, 3);
  int max_schedule = scop_max_loop_depth (scop) + 1;
  lambda_vector last_schedule = lambda_vector_new (max_schedule);

  if (VEC_length (graphite_bb_p, SCOP_BBS (scop)) == 0)
    return false;

  /* Get the data of the first bb.  */
  gb = VEC_index (graphite_bb_p, SCOP_BBS (scop), 0);
  last_nb_loops = gbb_nb_loops (gb);
  lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule,
                      last_nb_loops + 1);
  VEC_safe_push (graphite_bb_p, heap, bbs, gb);
  
  for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++)
    {
      /* We did the first bb before.  */
      if (i == 0)
        continue;

      nb_loops = gbb_nb_loops (gb);

      /* If the number of loops is unchanged and only the last element of the
         schedule changes, we stay in the loop nest.  */
      if (nb_loops == last_nb_loops 
          && (last_schedule [nb_loops + 1]
              != GBB_STATIC_SCHEDULE (gb)[nb_loops + 1]))
        {
          VEC_safe_push (graphite_bb_p, heap, bbs, gb);
          continue;
        }

      /* Otherwise, we left the innermost loop. So check, if the last bb was in
         a perfect loop nest and how many loops are contained in this perfect
         loop nest. 
         
         Count the number of zeros from the end of the schedule. They are the
         number of surrounding loops.

         Example:
         last_bb  2 3 2 0 0 0 0 3
         bb       2 4 0
	 <------  j = 4
        
         last_bb  2 3 2 0 0 0 0 3
         bb       2 3 2 0 1
	 <--  j = 2

         If there is no zero, there were other bbs in outer loops and the loop
         nest is not perfect.  */
      for (j = last_nb_loops - 1; j >= 0; j--)
        {
          if (last_schedule [j] != 0
              || (j <= nb_loops && GBB_STATIC_SCHEDULE (gb)[j] == 1))
            {
              j--;
              break;
            }
        }
      
      j++;

      /* Found perfect loop nest.  */
      if (perfect && last_nb_loops - j >= 2)
        transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j);
 
      /* Check if we start with a new loop.

         Example:
  
         last_bb  2 3 2 0 0 0 0 3
         bb       2 3 2 0 0 1 0
        
         Here we start with the loop "2 3 2 0 0 1" 

         last_bb  2 3 2 0 0 0 0 3
         bb       2 3 2 0 0 1 

         But here not, so the loop nest can never be perfect.  */

      perfect = (GBB_STATIC_SCHEDULE (gb)[nb_loops] == 0);

      /* Update the last_bb infos.  We do not do that for the bbs in the same
         loop, as the data we use is not changed.  */
      last_nb_loops = nb_loops;
      lambda_vector_copy (GBB_STATIC_SCHEDULE (gb), last_schedule,
                          nb_loops + 1);
      VEC_truncate (graphite_bb_p, bbs, 0);
      VEC_safe_push (graphite_bb_p, heap, bbs, gb);
    }

  /* Check if the last loop nest was perfect.  It is the same check as above,
     but the comparison with the next bb is missing.  */
  for (j = last_nb_loops - 1; j >= 0; j--)
    if (last_schedule [j] != 0)
      {
	j--;
	break;
      }

  j++;

  /* Found perfect loop nest.  */
  if (last_nb_loops - j >= 2)
    transform_done |= graphite_trans_loop_block (bbs, last_nb_loops - j);
  VEC_free (graphite_bb_p, heap, bbs);

  return transform_done;
}

/* Apply graphite transformations to all the basic blocks of SCOP.  */

static bool
graphite_apply_transformations (scop_p scop)
{
  bool transform_done = false;

  /* Sort the list of bbs.  Keep them always sorted.  */
  graphite_sort_gbbs (scop);

  if (flag_loop_block)
    transform_done = graphite_trans_scop_block (scop);

  /* Generate code even if we did not apply any real transformation.
     This also allows to check the performance for the identity
     transformation: GIMPLE -> GRAPHITE -> GIMPLE
     Keep in mind that CLooG optimizes in control, so the loop structure
     may change, even if we only use -fgraphite-identity.  */ 
  if (flag_graphite_identity)
    transform_done = true;

  return transform_done;
}

/* We limit all SCoPs to SCoPs, that are completely surrounded by a loop. 

   Example:

   for (i      |
     {         |
       for (j  |  SCoP 1
       for (k  |
     }         |

   * SCoP frontier, as this line is not surrounded by any loop. *

   for (l      |  SCoP 2

   This is necessary as scalar evolution and parameter detection need a
   outermost loop to initialize parameters correctly.  
  
   TODO: FIX scalar evolution and parameter detection to allow more flexible
         SCoP frontiers.  */

static void
limit_scops (void)
{
  VEC (sd_region, heap) *tmp_scops = VEC_alloc (sd_region, heap, 3);

  int i;
  scop_p scop;

  for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
    {
      int j;
      loop_p loop;
      build_scop_bbs (scop);

      if (!build_scop_loop_nests (scop))
	continue;

      for (j = 0; VEC_iterate (loop_p, SCOP_LOOP_NEST (scop), j, loop); j++) 
        if (!loop_in_sese_p (loop_outer (loop), SCOP_REGION (scop)))
          {
	    sd_region open_scop;
	    open_scop.entry = loop->header;
	    open_scop.exit = single_exit (loop)->dest;
	    VEC_safe_push (sd_region, heap, tmp_scops, &open_scop);
	  }
    }

  free_scops (current_scops);
  current_scops = VEC_alloc (scop_p, heap, 3);

  create_sese_edges (tmp_scops);
  build_graphite_scops (tmp_scops);
  VEC_free (sd_region, heap, tmp_scops);
}

/* Perform a set of linear transforms on the loops of the current
   function.  */

void
graphite_transform_loops (void)
{
  int i;
  scop_p scop;
  bool transform_done = false;

  if (number_of_loops () <= 1)
    return;

  current_scops = VEC_alloc (scop_p, heap, 3);
  recompute_all_dominators ();

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Graphite loop transformations \n");

  initialize_original_copy_tables ();
  cloog_initialize ();
  build_scops ();
  limit_scops ();

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\nnumber of SCoPs: %d\n",
	     VEC_length (scop_p, current_scops));

  for (i = 0; VEC_iterate (scop_p, current_scops, i, scop); i++)
    {
      build_scop_bbs (scop);
      if (!build_scop_loop_nests (scop))
	continue;

      build_bb_loops (scop);

      if (!build_scop_conditions (scop))
	continue;

      find_scop_parameters (scop);
      build_scop_context (scop);

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "\n(In SCoP %d:\n", i);
	  fprintf (dump_file, "\nnumber of bbs: %d\n",
		   VEC_length (graphite_bb_p, SCOP_BBS (scop)));
	  fprintf (dump_file, "\nnumber of loops: %d)\n",
		   VEC_length (loop_p, SCOP_LOOP_NEST (scop)));
	}

      if (!build_scop_iteration_domain (scop))
	continue;

      add_conditions_to_constraints (scop);
      build_scop_canonical_schedules (scop);

      build_scop_data_accesses (scop);
      build_scop_dynamic_schedules (scop);

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  int nbrefs = nb_data_refs_in_scop (scop);
	  fprintf (dump_file, "\nnumber of data refs: %d\n", nbrefs);
	}

      if (graphite_apply_transformations (scop))
        transform_done = gloog (scop, find_transform (scop));
#ifdef ENABLE_CHECKING
      else
	{
	  struct clast_stmt *stmt = find_transform (scop);
	  cloog_clast_free (stmt);
	}
#endif
    }

  /* Cleanup.  */
  if (transform_done)
    cleanup_tree_cfg ();

  free_scops (current_scops);
  cloog_finalize ();
  free_original_copy_tables ();
}

#else /* If Cloog is not available: #ifndef HAVE_cloog.  */

void
graphite_transform_loops (void)
{
  sorry ("Graphite loop optimizations cannot be used");
}

#endif
