
   /**-------------------------------------------------------------------**
    **                              CLooG                                **
    **-------------------------------------------------------------------**
    **                            program.c                              **
    **-------------------------------------------------------------------**
    **                 First version: october 25th 2001                  **
    **-------------------------------------------------------------------**/


/******************************************************************************
 *               CLooG : the Chunky Loop Generator (experimental)             *
 ******************************************************************************
 *                                                                            *
 * Copyright (C) 2001-2005 Cedric Bastoul                                     *
 *                                                                            *
 * This library is free software; you can redistribute it and/or              *
 * modify it under the terms of the GNU Lesser General Public                 *
 * License as published by the Free Software Foundation; either               *
 * version 2.1 of the License, or (at your option) any later version.         *
 *                                                                            *
 * This library 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          *
 * Lesser General Public License for more details.                            *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public           *
 * License along with this library; if not, write to the Free Software        *
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,                         *
 * Boston, MA  02110-1301  USA                                                *
 *                                                                            *
 * CLooG, the Chunky Loop Generator                                           *
 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr                         *
 *                                                                            *
 ******************************************************************************/
/* CAUTION: the english used for comments is probably the worst you ever read,
 *          please feel free to correct and improve it !
 */


# include <sys/types.h>
# include <sys/time.h>
#include <stdarg.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <ctype.h>
# include <unistd.h>
# include "../include/cloog/cloog.h"
#ifdef CLOOG_RUSAGE
# include <sys/resource.h>
#endif

#define ALLOC(type) (type*)malloc(sizeof(type))


/******************************************************************************
 *                          Structure display function                        *
 ******************************************************************************/


/**
 * cloog_program_print function:
 * this function is a human-friendly way to display the CloogProgram data
 * structure, it shows all the different fields and includes an indentation
 * level (level) in order to work with others print_structure functions.
 * - July 1st 2005: first version based on the old cloog_program_print function.
 */
void cloog_program_print_structure(file, program, level)
FILE * file ; 
CloogProgram * program ;
int level ;
{ int i, j ;

  /* Go to the right level. */
  for (i=0; i<level; i++)
  fprintf(file,"|\t") ;
  
  fprintf(file,"+-- CloogProgram\n") ;
  
  /* A blank line. */
  for (i=0; i<=level+1; i++)
  fprintf(file,"|\t") ;
  fprintf(file,"\n") ;
  
  /* Print the language. */
  for (i=0; i<=level; i++)
  fprintf(file,"|\t") ;
  fprintf(file, "Language: %c\n",program->language) ;
  
  /* A blank line. */
  for (i=0; i<=level+1; i++)
  fprintf(file,"|\t") ;
  fprintf(file,"\n") ;

  /* Print the scattering dimension number. */
  for (i=0; i<=level; i++)
  fprintf(file,"|\t") ;
  fprintf(file,"Scattering dimension number: %d\n",program->nb_scattdims) ;
  
  /* A blank line. */
  for (i=0; i<=level+1; i++)
  fprintf(file,"|\t") ;
  fprintf(file,"\n") ;
  
  /* Print the scalar scattering dimension informations. */
  for (i=0; i<=level; i++)
  fprintf(file,"|\t") ;
  if (program->scaldims != NULL)
  { fprintf(file,"Scalar dimensions:") ;
    for (i=0;i<program->nb_scattdims;i++)
    fprintf(file," %d:%d ",i,program->scaldims[i]) ;
    fprintf(file,"\n") ;
  }
  else
  fprintf(file,"No scalar scattering dimensions\n") ;
  
  /* A blank line. */
  for (i=0; i<=level+1; i++)
  fprintf(file,"|\t") ;
  fprintf(file,"\n") ;

  /* Print the parameter and the iterator names. */
  cloog_names_print_structure(file,program->names,level+1) ;
 
  /* A blank line. */
  for (i=0; i<=level+1; i++)
  fprintf(file,"|\t") ;
  fprintf(file,"\n") ;
  
  /* Print the context. */
  cloog_domain_print_structure(file, program->context, level+1, "Context");
    
  /* Print the loop. */
  cloog_loop_print_structure(file,program->loop,level+1) ;

  /* One more time something that is here only for a better look. */
  for (j=0; j<2; j++)
  { for (i=0; i<=level; i++)
    fprintf(file,"|\t") ;
      
    fprintf(file,"\n") ;
  }
}


/**
 * cloog_program_dump_cloog function:
 * This function dumps a CloogProgram structure supposed to be completely
 * filled in a CLooG input file (foo possibly stdout) such as CLooG can
 * rebuild almost exactly the data structure from the input file.
 *
 * If the scattering is already applied, the scattering parameter is supposed to
 * be NULL. In this case the number of scattering functions is lost, since they
 * are included inside the iteration domains. This can only lead to a less
 * beautiful pretty printing.
 *
 * In case the scattering is not yet applied it can be passed to this function
 * and will be included in the CLooG input file dump.
 */
void cloog_program_dump_cloog(FILE * foo, CloogProgram * program,
                              CloogScatteringList *scattering)
{
  int i;
  CloogLoop * loop ;
  CloogScatteringList *tmp_scatt;

  fprintf(foo,
  "# CLooG -> CLooG\n"
  "# This is an automatic dump of a CLooG input file from a CloogProgram data\n"
  "# structure. WARNING: it is highly dangerous and MAY be correct ONLY if\n"
  "# - it has been dumped before loop generation.\n"
  "# - option -noscalars is used (it removes scalar dimensions otherwise)\n"
  "# - option -l is at least the original scattering dimension number\n"
  "# ASK THE AUTHOR IF YOU *NEED* SOMETHING MORE ROBUST\n") ;

  /* Language. */
  if (program->language == 'c')
  fprintf(foo,"# Language: C\n") ;
  else
  fprintf(foo,"# Language: FORTRAN\n") ;
  fprintf(foo,"%c\n\n",program->language) ;

  /* Context. */
  fprintf(foo, "# Context (%d parameter(s)):\n", program->names->nb_parameters);
  cloog_domain_print_constraints(foo, program->context, 0);
  fprintf(foo,"1 # Parameter name(s)\n") ;
  for (i=0;i<program->names->nb_parameters;i++)
  fprintf(foo,"%s ",program->names->parameters[i]) ;

  /* Statement number. */
  i = 0 ;
  loop = program->loop ;
  while (loop != NULL)
  { i++ ;
    loop = loop->next ;
  }
  fprintf(foo,"\n\n# Statement number:\n%d\n\n",i) ;

  /* Iteration domains. */
  i = 1 ;
  loop = program->loop ;
  while (loop != NULL)
  { /* Name of the domain. */
    fprintf(foo,"# Iteration domain of statement %d.\n",i) ;

    cloog_domain_print_constraints(foo, loop->domain, 1);
    fprintf(foo,"0 0 0 # For future options.\n\n") ;
    
    i++ ;
    loop = loop->next ;
  }
  fprintf(foo,"\n1 # Iterator name(s)\n") ;

  /* Scattering already applied? In this case print the scattering names as
   * additional iterator names. */
  if (!scattering)
    for (i = 0; i < program->names->nb_scattering; i++)
      fprintf(foo, "%s ", program->names->scattering[i]);
  for (i=0;i<program->names->nb_iterators;i++)
    fprintf(foo,"%s ",program->names->iterators[i]);
  fprintf(foo,"\n\n") ;

  /* Exit, if scattering is already applied. */
  if (!scattering) {
    fprintf(foo, "# No scattering functions.\n0\n\n");
    return;
  }

  /* Scattering relations. */
  fprintf(foo, "# --------------------- SCATTERING --------------------\n");

  i = 0;
  for (tmp_scatt = scattering; tmp_scatt; tmp_scatt = tmp_scatt->next)
    i++;

  fprintf(foo, "%d # Scattering functions", i);

  for (tmp_scatt = scattering; tmp_scatt; tmp_scatt = tmp_scatt->next)
    cloog_scattering_print_constraints(foo, tmp_scatt->scatt);

  fprintf(foo, "\n1 # Scattering dimension name(s)\n");

  for (i = 0; i < program->names->nb_scattering; i++)
    fprintf(foo, "%s ", program->names->scattering[i]);
}


/**
 * cloog_program_print function:
 * This function prints the content of a CloogProgram structure (program) into a
 * file (file, possibly stdout).
 * - July 1st 2005: Now this very old function (probably as old as CLooG) is
 *                  only a frontend to cloog_program_print_structure, with a
 *                  quite better human-readable representation.
 */
void cloog_program_print(FILE * file, CloogProgram * program)
{ cloog_program_print_structure(file,program,0) ;
}


static void print_comment(FILE *file, CloogOptions *options,
			  const char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  if (options->language == CLOOG_LANGUAGE_FORTRAN) {
    fprintf(file, "! ");
    vfprintf(file, fmt, args);
    fprintf(file, "\n");
  } else {
    fprintf(file, "/* ");
    vfprintf(file, fmt, args);
    fprintf(file, " */\n");
  }
}

static void print_macros(FILE *file)
{
    fprintf(file, "/* Useful macros. */\n") ;
    fprintf(file,
	"#define floord(n,d) (((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))\n");
    fprintf(file,
	"#define ceild(n,d)  (((n)<0) ? -((-(n))/(d)) : ((n)+(d)-1)/(d))\n");
    fprintf(file, "#define max(x,y)    ((x) > (y) ? (x) : (y))\n") ; 
    fprintf(file, "#define min(x,y)    ((x) < (y) ? (x) : (y))\n\n") ; 
}

static void print_declarations(FILE *file, int n, char **names)
{
    int i;

    fprintf(file, "  int %s", names[0]); 
    for (i = 1; i < n; i++)
	fprintf(file, ", %s", names[i]); 

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

static void print_iterator_declarations(FILE *file, CloogProgram *program,
	CloogOptions *options)
{
    CloogNames *names = program->names;

    if (names->nb_scattering) {
	fprintf(file, "  /* Scattering iterators. */\n");
	print_declarations(file, names->nb_scattering, names->scattering);
    }
    if (names->nb_iterators) {
	fprintf(file, "  /* Original iterators. */\n");
	print_declarations(file, names->nb_iterators, names->iterators);
    }
}

static void print_callable_preamble(FILE *file, CloogProgram *program,
	CloogOptions *options)
{
    int j;
    CloogBlockList *blocklist;
    CloogBlock *block;
    CloogStatement *statement;

    fprintf(file, "extern void hash(int);\n\n");

    print_macros(file);

    for (blocklist = program->blocklist; blocklist; blocklist = blocklist->next) {
	block = blocklist->block;
	for (statement = block->statement; statement; statement = statement->next) {
	    fprintf(file, "#define S%d(", statement->number);
	    if (block->depth > 0) {
		fprintf(file, "%s", program->names->iterators[0]);
		for(j = 1; j < block->depth; j++)
		    fprintf(file, ",%s", program->names->iterators[j]);
	    }
	    fprintf(file,") { hash(%d);", statement->number);
	    for(j = 0; j < block->depth; j++)
		fprintf(file, " hash(%s);", program->names->iterators[j]);
	    fprintf(file, " }\n");
	}
    }
    fprintf(file, "\nvoid test("); 
    if (program->names->nb_parameters > 0) {
	fprintf(file, "int %s", program->names->parameters[0]);
	for(j = 1; j < program->names->nb_parameters; j++)
	    fprintf(file, ", int %s", program->names->parameters[j]);
    }
    fprintf(file, ")\n{\n"); 
    print_iterator_declarations(file, program, options);
}

static void print_callable_postamble(FILE *file, CloogProgram *program)
{
    fprintf(file, "}\n"); 
}

/**
 * cloog_program_pprint function:
 * This function prints the content of a CloogProgram structure (program) into a
 * file (file, possibly stdout), in a C-like language.
 * - June 22nd 2005: Adaptation for GMP.
 */
void cloog_program_pprint(file, program, options)
FILE * file ;
CloogProgram * program ;
CloogOptions * options ;
{
  int i, j, indentation = 0;
  CloogStatement * statement ;
  CloogBlockList * blocklist ;
  CloogBlock * block ;
  struct clast_stmt *root;
   
  if (program->language == 'f')
    options->language = CLOOG_LANGUAGE_FORTRAN ;
  else
    options->language = CLOOG_LANGUAGE_C ;
 
#ifdef CLOOG_RUSAGE
  print_comment(file, options, "Generated from %s by %s in %.2fs.",
		options->name, cloog_version(), options->time);
#else
  print_comment(file, options, "Generated from %s by %s.",
		options->name, cloog_version());
#endif
#ifdef CLOOG_MEMORY
  print_comment(file, options, "CLooG asked for %d KBytes.", options->memory);
  cloog_msg(CLOOG_INFO, "%.2fs and %dKB used for code generation.\n",
	  options->time,options->memory);
#endif
  
  /* If the option "compilable" is set, we provide the whole stuff to generate
   * a compilable code. This code just do nothing, but now the user can edit
   * the source and set the statement macros and parameters values.
   */
  if (options->compilable && (program->language == 'c'))
  { /* The headers. */
    fprintf(file,"/* DON'T FORGET TO USE -lm OPTION TO COMPILE. */\n\n") ;
    fprintf(file,"/* Useful headers. */\n") ;
    fprintf(file,"#include <stdio.h>\n") ;
    fprintf(file,"#include <stdlib.h>\n") ;
    fprintf(file,"#include <math.h>\n\n") ;

    /* The value of parameters. */
    fprintf(file,"/* Parameter value. */\n") ;
    for (i = 1; i <= program->names->nb_parameters; i++)
      fprintf(file, "#define PARVAL%d %d\n", i, options->compilable);
    
    /* The macros. */
    print_macros(file);

    /* The statement macros. */
    fprintf(file,"/* Statement macros (please set). */\n") ;
    blocklist = program->blocklist ;
    while (blocklist != NULL)
    { block = blocklist->block ;
      statement = block->statement ;
      while (statement != NULL)
      { fprintf(file,"#define S%d(",statement->number) ;
        if (block->depth > 0)
        { fprintf(file,"%s",program->names->iterators[0]) ;
          for(j=1;j<block->depth;j++)
          fprintf(file,",%s",program->names->iterators[j]) ;
        }
        fprintf(file,") {total++;") ;
	if (block->depth > 0) {
          fprintf(file, " printf(\"S%d %%d", statement->number);
          for(j=1;j<block->depth;j++)
            fprintf(file, " %%d");
          
          fprintf(file,"\\n\",%s",program->names->iterators[0]) ;
	  for(j=1;j<block->depth;j++)
          fprintf(file,",%s",program->names->iterators[j]) ;
          fprintf(file,");") ;
        }
        fprintf(file,"}\n") ;
        
	statement = statement->next ;
      }
      blocklist = blocklist->next ;
    }
    
    /* The iterator and parameter declaration. */
    fprintf(file,"\nint main() {\n") ; 
    print_iterator_declarations(file, program, options);
    if (program->names->nb_parameters > 0)
    { fprintf(file,"  /* Parameters. */\n") ;
      fprintf(file, "  int %s=PARVAL1",program->names->parameters[0]);
      for(i=2;i<=program->names->nb_parameters;i++)
        fprintf(file, ", %s=PARVAL%d", program->names->parameters[i-1], i);
      
      fprintf(file,";\n");
    }
    fprintf(file,"  int total=0;\n");
    fprintf(file,"\n") ;
    
    /* And we adapt the identation. */
    indentation += 2 ;
  } else if (options->callable && program->language == 'c') {
    print_callable_preamble(file, program, options);
    indentation += 2;
  }
  
  root = cloog_clast_create(program, options);
  clast_pprint(file, root, indentation, options);
  cloog_clast_free(root);
  
  /* The end of the compilable code in case of 'compilable' option. */
  if (options->compilable && (program->language == 'c'))
  {
    fprintf(file, "\n  printf(\"Number of integral points: %%d.\\n\",total);");
    fprintf(file, "\n  return 0;\n}\n");
  } else if (options->callable && program->language == 'c')
    print_callable_postamble(file, program);
}


/******************************************************************************
 *                         Memory deallocation function                       *
 ******************************************************************************/


/**
 * cloog_program_free function:
 * This function frees the allocated memory for a CloogProgram structure.
 */
void cloog_program_free(CloogProgram * program)
{ cloog_names_free(program->names) ;
  cloog_loop_free(program->loop) ;
  cloog_domain_free(program->context) ;
  cloog_block_list_free(program->blocklist) ;
  if (program->scaldims != NULL)
  free(program->scaldims) ;
  
  free(program) ;
}


/******************************************************************************
 *                               Reading function                             *
 ******************************************************************************/


static void cloog_program_construct_block_list(CloogProgram *p)
{
    CloogLoop *loop;
    CloogBlockList **next = &p->blocklist;

    for (loop = p->loop; loop; loop = loop->next) {
	*next = cloog_block_list_alloc(loop->block);
	next = &(*next)->next;
    }
}


/**
 * Construct a CloogProgram structure from a given context and
 * union domain representing the iteration domains and scattering functions.
 */
CloogProgram *cloog_program_alloc(CloogDomain *context, CloogUnionDomain *ud,
	CloogOptions *options)
{
  int i;
  char prefix[] = "c";
  CloogScatteringList * scatteringl;
  CloogNames *n;
  CloogProgram * p ;
      
  /* Memory allocation for the CloogProgram structure. */
  p = cloog_program_malloc() ;
  
  if (options->language == CLOOG_LANGUAGE_FORTRAN)
    p->language = 'f';
  else
    p->language = 'c';
    
  p->names = n = cloog_names_alloc();

  /* We then read the context data. */
  p->context = context;
  n->nb_parameters = ud->n_name[CLOOG_PARAM];
  
  /* First part of the CloogNames structure: the parameter names. */
  if (ud->name[CLOOG_PARAM]) {
    n->parameters = ud->name[CLOOG_PARAM];
    ud->name[CLOOG_PARAM] = NULL;
  } else
    n->parameters = cloog_names_generate_items(n->nb_parameters, NULL,
					       FIRST_PARAMETER);

  n->nb_iterators = ud->n_name[CLOOG_ITER];
  if (ud->name[CLOOG_ITER]) {
    n->iterators = ud->name[CLOOG_ITER];
    ud->name[CLOOG_ITER] = NULL;
  } else
    n->iterators = cloog_names_generate_items(n->nb_iterators, NULL,
					      FIRST_ITERATOR);

  if (ud->domain) {
    CloogNamedDomainList *l;
    CloogLoop **next = &p->loop;
    CloogScatteringList **next_scat = &scatteringl;

    scatteringl = NULL;
    for (i = 0, l = ud->domain; l; ++i, l = l->next) {
      *next = cloog_loop_from_domain(options->state, l->domain, i);
      l->domain = NULL;
      (*next)->block->statement->name = l->name;
      (*next)->block->statement->usr = l->usr;
      l->name = NULL;

      if (l->scattering) {
	*next_scat = ALLOC(CloogScatteringList);
	(*next_scat)->scatt = l->scattering;
	l->scattering = NULL;
	(*next_scat)->next = NULL;

	next_scat = &(*next_scat)->next;
      }

      next = &(*next)->next;
    }

    if (scatteringl != NULL) {
      p->nb_scattdims = cloog_scattering_dimension(scatteringl->scatt,
							    p->loop->domain);
      n->nb_scattering = p->nb_scattdims;
      if (ud->name[CLOOG_SCAT]) {
	n->scattering = ud->name[CLOOG_SCAT];
	ud->name[CLOOG_SCAT] = NULL;
      } else
	n->scattering = cloog_names_generate_items(n->nb_scattering, prefix, -1);
    
      /* The boolean array for scalar dimensions is created and set to 0. */
      p->scaldims = (int *)malloc(p->nb_scattdims*(sizeof(int))) ;
      if (p->scaldims == NULL) 
	cloog_die("memory overflow.\n");
      for (i=0;i<p->nb_scattdims;i++)
      p->scaldims[i] = 0 ;
      
      /* We try to find blocks in the input problem to reduce complexity. */
      if (!options->noblocks)
	cloog_program_block(p, scatteringl, options);
      if (!options->noscalars)
	cloog_program_extract_scalars(p, scatteringl, options);
      
      cloog_program_scatter(p, scatteringl, options);
      cloog_scattering_list_free(scatteringl);

      if (!options->noblocks)
	p->loop = cloog_loop_block(p->loop, p->scaldims, p->nb_scattdims);
    }
    else
    { p->nb_scattdims = 0 ;
      p->scaldims  = NULL ;
    }
  
    cloog_names_scalarize(p->names,p->nb_scattdims,p->scaldims) ;

    cloog_program_construct_block_list(p);
  }
  else
  { p->loop      = NULL ;
    p->blocklist = NULL ;
    p->scaldims  = NULL ;
  }

  cloog_union_domain_free(ud);
   
  return(p) ;
}


/**
 * cloog_program_read function:
 * This function read the informations to put in a CloogProgram structure from
 * a file (file, possibly stdin). It returns a pointer to a CloogProgram
 * structure containing the read informations.
 * - October 25th 2001: first version.
 * - September 9th 2002: - the big reading function is now split in several
 *                         functions (one per read data structure).
 *                       - adaptation to the new file format with naming.
 */
CloogProgram *cloog_program_read(FILE *file, CloogOptions *options)
{
  CloogInput *input;
  CloogProgram *p;

  input = cloog_input_read(file, options);
  p = cloog_program_alloc(input->context, input->ud, options);
  free(input);

  return p;
}


/******************************************************************************
 *                            Processing functions                            *
 ******************************************************************************/
 
 
/**
 * cloog_program_malloc function:
 * This function allocates the memory space for a CloogProgram structure and
 * sets its fields with default values. Then it returns a pointer to the
 * allocated space.
 * - November 21th 2005: first version.
 */
CloogProgram * cloog_program_malloc()
{ CloogProgram * program ;
  
  /* Memory allocation for the CloogProgram structure. */
  program = (CloogProgram *)malloc(sizeof(CloogProgram)) ;
  if (program == NULL) 
    cloog_die("memory overflow.\n");
  
  /* We set the various fields with default values. */
  program->language     = 'c' ;
  program->nb_scattdims = 0 ;
  program->context      = NULL ;
  program->loop         = NULL ;
  program->names        = NULL ;
  program->blocklist    = NULL ;
  program->scaldims     = NULL ;
  program->usr          = NULL;
  
  return program ;
}  


/**
 * cloog_program_generate function:
 * This function calls the Quillere algorithm for loop scanning. (see the
 * Quillere paper) and calls the loop simplification function.
 * - depth is the loop depth we want to optimize (guard free as possible),
 *   the first loop depth is 1 and anegative value is the infinity depth.
 * - sep_level is the level number where we want to start loop separation.
 **
 * - October 26th 2001: first version. 
 * - April   19th 2005: some basic fixes and memory usage feature.
 * - April   29th 2005: (bug fix, bug found by DaeGon Kim) see case 2 below.
 */ 
CloogProgram * cloog_program_generate(program, options)
CloogProgram * program ;
CloogOptions * options ;
{
#ifdef CLOOG_RUSAGE
  float time;
  struct rusage start, end ;
#endif
  CloogLoop * loop ;
#ifdef CLOOG_MEMORY
  char status_path[MAX_STRING_VAL] ;
  FILE * status ;
 
  /* We initialize the memory need to 0. */
  options->memory = 0 ;
#endif

  if (options->override)
  {
    cloog_msg(options, CLOOG_WARNING,
    "you are using -override option, be aware that the "
    "generated\n                code may be incorrect.\n") ;
  }
  else
  { /* Playing with options may be dangerous, here are two possible issues :
     * 1. Using -l option less than scattering dimension number may lead to
     *    an illegal target code (since the scattering is not respected), if
     *    it is the case, we set -l depth to the first acceptable value.
     */
    if ((program->nb_scattdims > options->l) && (options->l >= 0))
    {
      cloog_msg(options, CLOOG_WARNING,
      "-l depth is less than the scattering dimension number "
      "(the \n                generated code may be incorrect), it has been "
      "automaticaly set\n                to this value (use option -override "
      "to override).\n") ;
      options->l = program->nb_scattdims ;
    }
      
    /* 2. Using -f option greater than one while -l depth is greater than the
     *    scattering dimension number may lead to iteration duplication (try
     *    test/daegon_lu_osp.cloog with '-f 3' to test) because of the step 4b
     *    of the cloog_loop_generate function, if it is the case, we set -l to
     *    the first acceptable value.
     */
    if (((options->f > 1) || (options->f < 0)) &&
        ((options->l > program->nb_scattdims) || (options->l < 0)))
    {
      cloog_msg(options, CLOOG_WARNING,
      "-f depth is more than one, -l depth has been "
      "automaticaly set\n                to the scattering dimension number "
      "(target code may have\n                duplicated iterations), -l depth "
      "has been automaticaly set to\n                this value (use option "
      "-override to override).\n") ;
      options->l = program->nb_scattdims ;
    }
  }
  
#ifdef CLOOG_RUSAGE
  getrusage(RUSAGE_SELF, &start) ;
#endif
  if (program->loop != NULL)
  { loop = program->loop ;
    
    /* Here we go ! */
    loop = cloog_loop_generate(loop, program->context, 0, 0,
                               program->scaldims,
			       program->nb_scattdims,
			       options);
			          
#ifdef CLOOG_MEMORY
    /* We read into the status file of the process how many memory it uses. */
    sprintf(status_path,"/proc/%d/status",getpid()) ;
    status = fopen(status_path, "r") ;
    while (fscanf(status,"%s",status_path) && strcmp(status_path,"VmData:")!=0);
    fscanf(status,"%d",&(options->memory)) ;
    fclose(status) ;
#endif
    
    if ((!options->nosimplify) && (program->loop != NULL))
      loop = cloog_loop_simplify(loop, program->context, 0,
                                 program->nb_scattdims, options);
   
    program->loop = loop ;
  }
    
#ifdef CLOOG_RUSAGE
  getrusage(RUSAGE_SELF, &end) ;
  /* We calculate the time spent in code generation. */
  time =  (end.ru_utime.tv_usec -  start.ru_utime.tv_usec)/(float)(MEGA) ;
  time += (float)(end.ru_utime.tv_sec - start.ru_utime.tv_sec) ;
  options->time = time ;
#endif
  
  return program ;
}


/**
 * cloog_program_block function:
 * this function gives a last chance to the lazy user to consider statement
 * blocks instead of some statement lists where the whole list may be
 * considered as a single statement from a code generation point of view.
 * For instance two statements with the same iteration domain and the same
 * scattering functions may be considered as a block. This function is lazy
 * and can only find very simple forms of trivial blocks (see
 * cloog_domain_lazy_block function for more details). The useless loops and
 * scattering functions are removed and freed while the statement list of
 * according blocks are filled.
 * - program is the whole program structure (befaore applying scattering),
 * - scattering is the list of scattering functions.
 **
 * - April   30th 2005: first attempt.
 * - June 10-11th 2005: first working version.
 */
void cloog_program_block(CloogProgram *program,
	CloogScatteringList *scattering, CloogOptions *options)
{ int blocked_reference=0, blocked=0, nb_blocked=0 ;
  CloogLoop * reference, * start, * loop ;
  CloogScatteringList * scatt_reference, * scatt_loop, * scatt_start;
  
  if ((program->loop == NULL) || (program->loop->next == NULL))
  return ;
  
  /* The process will use three variables for the linked list :
   * - 'start' is the starting point of a new block,
   * - 'reference' is the node of the block used for the block checking,
   * - 'loop' is the candidate to be inserted inside the block.
   * At the beginning of the process, the linked lists are as follow:
   *         O------>O------>O------>O------>NULL
   *         |       |
   *       start    loop
   *     reference
   */

  reference       = program->loop ;
  start           = program->loop ;
  loop            = reference->next ;
  scatt_reference = scattering ;
  scatt_start     = scattering ;
  scatt_loop      = scattering->next ;
   
  while (loop != NULL)
  { if (cloog_domain_lazy_equal(reference->domain,loop->domain) &&
        cloog_scattering_lazy_block(scatt_reference->scatt, scatt_loop->scatt,
	                        scattering,program->nb_scattdims))
    { /* If we find a block we update the links:
       *     +---------------+
       *     |               v
       *     O       O------>O------>O------>NULL
       *     |       |
       *   start    loop
       * reference
       */
      blocked = 1 ;
      nb_blocked ++ ;
      cloog_block_merge(start->block,loop->block); /* merge frees loop->block */
      loop->block = NULL ;
      start->next = loop->next ;
      scatt_start->next = scatt_loop->next ;
    }
    else
    { /* If we didn't find a block, the next start of a block is updated:
       *     O------>O------>O------>O------>NULL
       *     |       |
       * reference start
       *           loop
       */
      blocked= 0 ;
      start = loop ;
      scatt_start = scatt_loop ;
    }

    /* If the reference node has been included into a block, we can free it. */
    if (blocked_reference)
    { reference->next = NULL ;
      cloog_loop_free(reference) ;
      cloog_scattering_free(scatt_reference->scatt);
      free(scatt_reference) ;
    }
    
    /* The reference and the loop are now updated for the next try, the
     * starting position depends on the previous step.
     *       O   ?   O------>O------>O------>NULL
     *               |       |
     *           reference loop
     */
    reference       = loop ;
    loop            = loop->next ;
    scatt_reference = scatt_loop ;
    scatt_loop      = scatt_loop->next ;
    
    /* We mark the new reference as being blocked or not, if will be freed
     * during the next while loop execution.
     */
    if (blocked)
    blocked_reference = 1 ;
    else
    blocked_reference = 0 ;
  }
  
  /* We free the last blocked reference if any (since in the while loop it was
   * freed during the next loop execution, it was not possible to free the
   * last one inside).
   */
  if (blocked_reference)
  { reference->next = NULL ;
    cloog_loop_free(reference) ;
    cloog_scattering_free(scatt_reference->scatt);
    free(scatt_reference) ;
  }
  
  if (nb_blocked != 0)
    cloog_msg(options, CLOOG_INFO, "%d domains have been blocked.\n", nb_blocked);
}


/**
 * cloog_program_extract_scalars function:
 * this functions finds and removes the dimensions of the scattering functions
 * when they are scalar (i.e. of the shape "dim + scalar = 0") for all
 * scattering functions. The reason is that the processing of such dimensions
 * is trivial and do not need neither a row and a column in the matrix
 * representation of the domain (this will save memory) neither the full
 * Quillere processing (this will save time). The scalar dimensions data are
 * dispatched in the CloogProgram structure (the boolean vector scaldims will
 * say which original dimensions are scalar or not) and to the CloogBlock
 * structures (each one has a scaldims vector that contains the scalar values).
 * - June 14th 2005: first developments.
 * - June 30th 2005: first version.
 */ 
void cloog_program_extract_scalars(CloogProgram *program,
	CloogScatteringList *scattering, CloogOptions *options)
{ int i, j, scalar, current, nb_scaldims=0 ;
  CloogScatteringList *start;
  CloogScattering *old;
  CloogLoop *loop;
  CloogBlock * block ;

  start = scattering ;
    
  for (i=0;i<program->nb_scattdims;i++)
  { scalar = 1 ;
    scattering = start ;
    while (scattering != NULL)
    { if (!cloog_scattering_lazy_isscalar(scattering->scatt, i, NULL))
      { scalar = 0 ;
        break ;
      }
      scattering = scattering->next ;
    }
    
    if (scalar)
    { nb_scaldims ++ ;
      program->scaldims[i] = 1 ;
    }
  }
  
  /* If there are no scalar dimensions, we can continue directly. */
  if (!nb_scaldims)
  return ;

  /* Otherwise, in each block, we have to put the number of scalar dimensions,
   * and to allocate the memory for the scalar values.
   */
  for (loop = program->loop; loop; loop = loop->next) {
    block = loop->block;
    block->nb_scaldims = nb_scaldims ;
    block->scaldims = (cloog_int_t *)malloc(nb_scaldims*sizeof(cloog_int_t));
    for (i=0;i<nb_scaldims;i++)
    cloog_int_init(block->scaldims[i]);
  }
  
  /* Then we have to fill these scalar values, so we can erase those dimensions
   * from the scattering functions. It's easier to begin with the last one,
   * since there would be an offset otherwise (if we remove the i^th dimension,
   * then the next one is not the (i+1)^th but still the i^th...).
   */
  current = nb_scaldims - 1 ;
  for (i=program->nb_scattdims-1;i>=0;i--)
  if (program->scaldims[i])
  {
    scattering = start ;
    for (loop = program->loop; loop; loop = loop->next) {
      block = loop->block;
      if (!cloog_scattering_lazy_isscalar(scattering->scatt, i,
						&block->scaldims[current])) {
	/* We should have found a scalar value: if not, there is an error. */
	cloog_die("dimension %d is not scalar as expected.\n", i);
      }
      scattering = scattering->next ;
    } 
  
    scattering = start ;
    while (scattering != NULL) {
      old = scattering->scatt;
      scattering->scatt = cloog_scattering_erase_dimension(old, i);
      cloog_scattering_free(old);
      scattering = scattering->next ;
    }
    current-- ;
  }
  
  /* We postprocess the scaldims array in such a way that each entry is how
   * many scalar dimensions follows + 1 (the current one). This will make 
   * some other processing easier (e.g. knowledge of some offsets).
   */
  for (i=0;i<program->nb_scattdims-1;i++)
  { if (program->scaldims[i])
    { j = i + 1 ;
      while ((j < program->nb_scattdims) && program->scaldims[j])
      { program->scaldims[i] ++ ;
        j ++ ;
      }
    }
  }
  
  if (nb_scaldims != 0)
    cloog_msg(options, CLOOG_INFO, "%d dimensions (over %d) are scalar.\n",
          nb_scaldims,program->nb_scattdims) ;
}


/**
 * cloog_program_scatter function:
 * This function adds the scattering (scheduling) informations in a program.
 * If names is NULL, this function create names itself such that the i^th
 * name is ci.
 * - November 6th 2001: first version. 
 */
void cloog_program_scatter(CloogProgram *program,
			CloogScatteringList *scattering, CloogOptions *options)
{ int scattering_dim, scattering_dim2, not_enough_constraints=0 ;
  CloogLoop * loop ;
  
  if ((program != NULL) && (scattering != NULL))
  { loop = program->loop ;
    
    /* We compute the scattering dimension and check it is >=0. */
    scattering_dim = cloog_scattering_dimension(scattering->scatt, loop->domain);
    if (scattering_dim < 0)
      cloog_die("scattering has not enough dimensions.\n");
    if (!cloog_scattering_fully_specified(scattering->scatt, loop->domain))
    not_enough_constraints ++ ;
         
    /* The scattering dimension may have been modified by scalar extraction. */
    scattering_dim = cloog_scattering_dimension(scattering->scatt, loop->domain);

    /* Finally we scatter all loops. */
    cloog_loop_scatter(loop, scattering->scatt);
    loop = loop->next ;
    scattering = scattering->next ;    
    
    while ((loop != NULL) && (scattering != NULL))
    { scattering_dim2 = cloog_scattering_dimension(scattering->scatt,
								loop->domain);
      if (scattering_dim2 != scattering_dim)
        cloog_die("scattering dimensions are not the same.\n") ;
      if (!cloog_scattering_fully_specified(scattering->scatt, loop->domain))
      not_enough_constraints ++ ;
      
      cloog_loop_scatter(loop, scattering->scatt);
      loop = loop->next ;
      scattering = scattering->next ;
    }
    if ((loop != NULL) || (scattering != NULL))
      cloog_msg(options, CLOOG_WARNING,
                    "there is not a scattering for each statement.\n");
    
    if (not_enough_constraints)
      cloog_msg(options, CLOOG_WARNING, "not enough constraints for "
                    "%d scattering function(s).\n",not_enough_constraints) ;
  }
}
