//===- ScopLib.cpp - ScopLib interface ------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// ScopLib Interface
//
//===----------------------------------------------------------------------===//

#include "polly/LinkAllPasses.h"

#ifdef SCOPLIB_FOUND

#include "polly/Dependences.h"
#include "polly/ScopLib.h"
#include "polly/ScopInfo.h"

#include "llvm/Support/CommandLine.h"
#include "llvm/Assembly/Writer.h"

#include "stdio.h"
#include "isl/set.h"
#include "isl/map.h"
#include "isl/constraint.h"

using namespace llvm;

namespace polly {

ScopLib::ScopLib(Scop *S) : PollyScop(S) {
  scoplib = scoplib_scop_malloc();

  initializeArrays();
  initializeParameters();
  initializeScattering();
  initializeStatements();
}

ScopLib::ScopLib(Scop *S, FILE *F, Dependences *dep) : PollyScop(S), D(dep) {
  scoplib = scoplib_scop_read(F);
}

void ScopLib::initializeParameters() {
  scoplib->nb_parameters = PollyScop->getNumParams();
  scoplib->parameters =
      (char **)malloc(sizeof(char *) * scoplib->nb_parameters);

  for (int i = 0; i < scoplib->nb_parameters; ++i) {
    scoplib->parameters[i] = (char *)malloc(sizeof(char *) * 20);
    sprintf(scoplib->parameters[i], "p_%d", i);
  }
}

void ScopLib::initializeArrays() {
  int nb_arrays = 0;

  for (Scop::iterator SI = PollyScop->begin(), SE = PollyScop->end(); SI != SE;
       ++SI)
    for (ScopStmt::memacc_iterator MI = (*SI)->memacc_begin(),
                                   ME = (*SI)->memacc_end();
         MI != ME; ++MI) {
      const Value *BaseAddr = (*MI)->getBaseAddr();
      if (ArrayMap.find(BaseAddr) == ArrayMap.end()) {
        ArrayMap.insert(std::make_pair(BaseAddr, nb_arrays));
        ++nb_arrays;
      }
    }

  scoplib->nb_arrays = nb_arrays;
  scoplib->arrays = (char **)malloc(sizeof(char *) * nb_arrays);

  for (int i = 0; i < nb_arrays; ++i)
    for (std::map<const Value *, int>::iterator VI = ArrayMap.begin(),
                                                VE = ArrayMap.end();
         VI != VE; ++VI)
      if ((*VI).second == i) {
        const Value *V = (*VI).first;
        std::string name = V->getName();
        scoplib->arrays[i] = (char *)malloc(sizeof(char *) * (name.size() + 1));
        strcpy(scoplib->arrays[i], name.c_str());
      }
}

void ScopLib::initializeScattering() {}

scoplib_statement_p ScopLib::initializeStatement(ScopStmt *stmt) {
  scoplib_statement_p Stmt = scoplib_statement_malloc();

  // Domain & Schedule
  Stmt->domain = scoplib_matrix_list_malloc();
  Stmt->domain->elt = domainToMatrix(stmt->getDomain());
  Stmt->schedule = scatteringToMatrix(stmt->getScattering());

  // Statement name
  std::string entryName;
  raw_string_ostream OS(entryName);
  WriteAsOperand(OS, stmt->getBasicBlock(), false);
  entryName = OS.str();
  Stmt->body = (char *)malloc(sizeof(char) * (entryName.size() + 1));
  strcpy(Stmt->body, entryName.c_str());

  // Iterator names
  Stmt->nb_iterators = stmt->getNumIterators();
  Stmt->iterators = (char **)malloc(sizeof(char *) * Stmt->nb_iterators);

  for (int i = 0; i < Stmt->nb_iterators; ++i) {
    Stmt->iterators[i] = (char *)malloc(sizeof(char *) * 20);
    sprintf(Stmt->iterators[i], "i_%d", i);
  }

  // Memory Accesses
  Stmt->read = createAccessMatrix(stmt, true);
  Stmt->write = createAccessMatrix(stmt, false);

  return Stmt;
}

void ScopLib::initializeStatements() {
  for (Scop::reverse_iterator SI = PollyScop->rbegin(), SE = PollyScop->rend();
       SI != SE; ++SI) {
    scoplib_statement_p stmt = initializeStatement(*SI);
    stmt->next = scoplib->statement;
    scoplib->statement = stmt;
  }
}

void ScopLib::freeStatement(scoplib_statement_p stmt) {

  if (stmt->read)
    scoplib_matrix_free(stmt->read);
  stmt->read = NULL;

  if (stmt->write)
    scoplib_matrix_free(stmt->write);
  stmt->write = NULL;

  scoplib_matrix_list_p current = stmt->domain;
  while (current) {
    scoplib_matrix_list_p next = current->next;
    current->next = NULL;
    scoplib_matrix_free(current->elt);
    current->elt = NULL;
    scoplib_matrix_list_free(current);
    current = next;
  }
  stmt->domain = NULL;

  if (stmt->schedule)
    scoplib_matrix_free(stmt->schedule);
  stmt->schedule = NULL;

  for (int i = 0; i < stmt->nb_iterators; ++i)
    free(stmt->iterators[i]);

  free(stmt->iterators);
  stmt->iterators = NULL;
  stmt->nb_iterators = 0;

  scoplib_statement_free(stmt);
}

void ScopLib::print(FILE *F) { scoplib_scop_print_dot_scop(F, scoplib); }

/// Add an isl constraint to an ScopLib matrix.
///
/// @param user The matrix
/// @param c The constraint
int ScopLib::domainToMatrix_constraint(isl_constraint *c, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p)user;

  int nb_params = isl_constraint_dim(c, isl_dim_param);
  int nb_vars = isl_constraint_dim(c, isl_dim_set);
  int nb_div = isl_constraint_dim(c, isl_dim_div);

  assert(!nb_div && "Existentially quantified variables not yet supported");

  scoplib_vector_p vec = scoplib_vector_malloc(nb_params + nb_vars + 2);

  // Assign type
  if (isl_constraint_is_equality(c))
    scoplib_vector_tag_equality(vec);
  else
    scoplib_vector_tag_inequality(vec);

  isl_int v;
  isl_int_init(v);

  // Assign variables
  for (int i = 0; i < nb_vars; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_set, i, &v);
    isl_int_set(vec->p[i + 1], v);
  }

  // Assign parameters
  for (int i = 0; i < nb_params; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
    isl_int_set(vec->p[nb_vars + i + 1], v);
  }

  // Assign constant
  isl_constraint_get_constant(c, &v);
  isl_int_set(vec->p[nb_params + nb_vars + 1], v);

  scoplib_matrix_insert_vector(m, vec, m->NbRows);

  scoplib_vector_free(vec);
  isl_constraint_free(c);
  isl_int_clear(v);

  return 0;
}

/// Add an isl basic set to a ScopLib matrix_list
///
/// @param bset The basic set to add
/// @param user The matrix list we should add the basic set to
///
/// XXX: At the moment this function expects just a matrix, as support
/// for matrix lists is currently not available in ScopLib. So union of
/// polyhedron are not yet supported
int ScopLib::domainToMatrix_basic_set(isl_basic_set *bset, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p)user;
  assert(!m->NbRows && "Union of polyhedron not yet supported");

  isl_basic_set_foreach_constraint(bset, &domainToMatrix_constraint, user);
  isl_basic_set_free(bset);
  return 0;
}

/// Translate a isl_set to a ScopLib matrix.
///
/// @param PS The set to be translated
/// @return A ScopLib Matrix
scoplib_matrix_p ScopLib::domainToMatrix(__isl_take isl_set *set) {
  set = isl_set_compute_divs(set);
  set = isl_set_align_divs(set);

  // Initialize the matrix.
  unsigned NbRows, NbColumns;
  NbRows = 0;
  NbColumns = isl_set_n_dim(set) + isl_set_n_param(set) + 2;
  scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns);

  // Copy the content into the matrix.
  isl_set_foreach_basic_set(set, &domainToMatrix_basic_set, matrix);

  isl_set_free(set);

  return matrix;
}

/// Add an isl constraint to an ScopLib matrix.
///
/// @param user The matrix
/// @param c The constraint
int ScopLib::scatteringToMatrix_constraint(isl_constraint *c, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p)user;

  int nb_params = isl_constraint_dim(c, isl_dim_param);
  int nb_in = isl_constraint_dim(c, isl_dim_in);
  int nb_div = isl_constraint_dim(c, isl_dim_div);

  assert(!nb_div && "Existentially quantified variables not yet supported");

  scoplib_vector_p vec = scoplib_vector_malloc(nb_params + nb_in + 2);

  // Assign type
  if (isl_constraint_is_equality(c))
    scoplib_vector_tag_equality(vec);
  else
    scoplib_vector_tag_inequality(vec);

  isl_int v;
  isl_int_init(v);

  // Assign variables
  for (int i = 0; i < nb_in; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_in, i, &v);
    isl_int_set(vec->p[i + 1], v);
  }

  // Assign parameters
  for (int i = 0; i < nb_params; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
    isl_int_set(vec->p[nb_in + i + 1], v);
  }

  // Assign constant
  isl_constraint_get_constant(c, &v);
  isl_int_set(vec->p[nb_in + nb_params + 1], v);

  scoplib_vector_p null = scoplib_vector_malloc(nb_params + nb_in + 2);

  vec = scoplib_vector_sub(null, vec);
  scoplib_matrix_insert_vector(m, vec, 0);

  isl_constraint_free(c);
  isl_int_clear(v);

  return 0;
}

/// Add an isl basic map to a ScopLib matrix_list
///
/// @param bmap The basic map to add
/// @param user The matrix list we should add the basic map to
///
/// XXX: At the moment this function expects just a matrix, as support
/// for matrix lists is currently not available in ScopLib. So union of
/// polyhedron are not yet supported
int ScopLib::scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p)user;
  assert(!m->NbRows && "Union of polyhedron not yet supported");

  isl_basic_map_foreach_constraint(bmap, &scatteringToMatrix_constraint, user);
  isl_basic_map_free(bmap);
  return 0;
}

/// Translate a isl_map to a ScopLib matrix.
///
/// @param map The map to be translated
/// @return A ScopLib Matrix
scoplib_matrix_p ScopLib::scatteringToMatrix(__isl_take isl_map *map) {
  map = isl_map_compute_divs(map);
  map = isl_map_align_divs(map);

  // Initialize the matrix.
  unsigned NbRows, NbColumns;
  NbRows = 0;
  NbColumns = isl_map_n_in(map) + isl_map_n_param(map) + 2;
  scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns);

  // Copy the content into the matrix.
  isl_map_foreach_basic_map(map, &scatteringToMatrix_basic_map, matrix);

  // Only keep the relevant rows.
  scoplib_matrix_p reduced =
      scoplib_matrix_ncopy(matrix, isl_map_n_in(map) * 2 + 1);

  scoplib_matrix_free(matrix);
  isl_map_free(map);

  return reduced;
}

/// Add an isl constraint to an ScopLib matrix.
///
/// @param user The matrix
/// @param c The constraint
int ScopLib::accessToMatrix_constraint(isl_constraint *c, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p)user;

  int nb_params = isl_constraint_dim(c, isl_dim_param);
  int nb_in = isl_constraint_dim(c, isl_dim_in);
  int nb_div = isl_constraint_dim(c, isl_dim_div);

  assert(!nb_div && "Existentially quantified variables not yet supported");

  scoplib_vector_p vec = scoplib_vector_malloc(nb_params + nb_in + 2);

  isl_int v;
  isl_int_init(v);

  // The access dimension has to be one.
  isl_constraint_get_coefficient(c, isl_dim_out, 0, &v);
  assert((isl_int_is_one(v) || isl_int_is_negone(v)) &&
         "Access relations not supported in scoplib");
  bool inverse = isl_int_is_one(v);

  // Assign variables
  for (int i = 0; i < nb_in; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_in, i, &v);

    if (inverse)
      isl_int_neg(v, v);

    isl_int_set(vec->p[i + 1], v);
  }

  // Assign parameters
  for (int i = 0; i < nb_params; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_param, i, &v);

    if (inverse)
      isl_int_neg(v, v);

    isl_int_set(vec->p[nb_in + i + 1], v);
  }

  // Assign constant
  isl_constraint_get_constant(c, &v);

  if (inverse)
    isl_int_neg(v, v);

  isl_int_set(vec->p[nb_in + nb_params + 1], v);

  scoplib_matrix_insert_vector(m, vec, m->NbRows);

  isl_constraint_free(c);
  isl_int_clear(v);

  return 0;
}

/// Add an isl basic map to a ScopLib matrix_list
///
/// @param bmap The basic map to add
/// @param user The matrix list we should add the basic map to
///
/// XXX: At the moment this function expects just a matrix, as support
/// for matrix lists is currently not available in ScopLib. So union of
/// polyhedron are not yet supported
int ScopLib::accessToMatrix_basic_map(isl_basic_map *bmap, void *user) {
  isl_basic_map_foreach_constraint(bmap, &accessToMatrix_constraint, user);
  isl_basic_map_free(bmap);
  return 0;
}

/// Create the memory access matrix for scoplib
///
/// @param S The polly statement the access matrix is created for.
/// @param isRead Are we looking for read or write accesses?
/// @param ArrayMap A map translating from the memory references to the scoplib
/// indeces
///
/// @return The memory access matrix, as it is required by scoplib.
scoplib_matrix_p ScopLib::createAccessMatrix(ScopStmt *S, bool isRead) {

  unsigned NbColumns = S->getNumIterators() + S->getNumParams() + 2;
  scoplib_matrix_p m = scoplib_matrix_malloc(0, NbColumns);

  for (ScopStmt::memacc_iterator MI = S->memacc_begin(), ME = S->memacc_end();
       MI != ME; ++MI)
    if ((*MI)->isRead() == isRead) {
      // Extract the access function.
      isl_map *AccessRelation = (*MI)->getAccessRelation();
      isl_map_foreach_basic_map(AccessRelation, &accessToMatrix_basic_map, m);
      isl_map_free(AccessRelation);

      // Set the index of the memory access base element.
      std::map<const Value *, int>::iterator BA =
          ArrayMap.find((*MI)->getBaseAddr());
      isl_int_set_si(m->p[m->NbRows - 1][0], (*BA).second + 1);
    }

  return m;
}

ScopLib::~ScopLib() {
  if (!scoplib)
    return;

  // Free array names.
  for (int i = 0; i < scoplib->nb_arrays; ++i)
    free(scoplib->arrays[i]);

  free(scoplib->arrays);
  scoplib->arrays = NULL;
  scoplib->nb_arrays = 0;

  // Free parameters
  for (int i = 0; i < scoplib->nb_parameters; ++i)
    free(scoplib->parameters[i]);

  free(scoplib->parameters);
  scoplib->parameters = NULL;
  scoplib->nb_parameters = 0;

  scoplib_statement_p stmt = scoplib->statement;

  // Free Statements
  while (stmt) {
    scoplib_statement_p TempStmt = stmt->next;
    stmt->next = NULL;
    freeStatement(stmt);
    stmt = TempStmt;
  }

  scoplib->statement = NULL;

  scoplib_scop_free(scoplib);
}
/// @brief Create an isl constraint from a row of OpenScop integers.
///
/// @param row An array of isl/OpenScop integers.
/// @param Space An isl space object, describing how to spilt the dimensions.
///
/// @return An isl constraint representing this integer array.
isl_constraint *constraintFromMatrixRow(isl_int *row,
                                        __isl_take isl_space *Space) {
  isl_constraint *c;

  unsigned NbIn = isl_space_dim(Space, isl_dim_in);
  unsigned NbParam = isl_space_dim(Space, isl_dim_param);

  if (isl_int_is_zero(row[0]))
    c = isl_equality_alloc(isl_local_space_from_space(Space));
  else
    c = isl_inequality_alloc(isl_local_space_from_space(Space));

  unsigned current_column = 1;

  for (unsigned j = 0; j < NbIn; ++j)
    isl_constraint_set_coefficient(c, isl_dim_in, j, row[current_column++]);

  for (unsigned j = 0; j < NbParam; ++j)
    isl_constraint_set_coefficient(c, isl_dim_param, j, row[current_column++]);

  isl_constraint_set_constant(c, row[current_column]);

  return c;
}

/// @brief Create an isl map from a OpenScop matrix.
///
/// @param m The OpenScop matrix to translate.
/// @param Space The dimensions that are contained in the OpenScop matrix.
///
/// @return An isl map representing m.
isl_map *mapFromMatrix(scoplib_matrix_p m, __isl_take isl_space *Space,
                       unsigned scatteringDims) {
  isl_basic_map *bmap = isl_basic_map_universe(isl_space_copy(Space));

  for (unsigned i = 0; i < m->NbRows; ++i) {
    isl_constraint *c;

    c = constraintFromMatrixRow(m->p[i], isl_space_copy(Space));

    mpz_t minusOne;
    mpz_init(minusOne);
    mpz_set_si(minusOne, -1);
    isl_constraint_set_coefficient(c, isl_dim_out, i, minusOne);

    bmap = isl_basic_map_add_constraint(bmap, c);
  }

  for (unsigned i = m->NbRows; i < scatteringDims; i++) {
    isl_constraint *c;

    c = isl_equality_alloc(isl_local_space_from_space(isl_space_copy(Space)));

    mpz_t One;
    mpz_init(One);
    mpz_set_si(One, 1);
    isl_constraint_set_coefficient(c, isl_dim_out, i, One);

    bmap = isl_basic_map_add_constraint(bmap, c);
  }

  isl_space_free(Space);

  return isl_map_from_basic_map(bmap);
}
/// @brief Create an isl constraint from a row of OpenScop integers.
///
/// @param row An array of isl/OpenScop integers.
/// @param Space An isl space object, describing how to spilt the dimensions.
///
/// @return An isl constraint representing this integer array.
isl_constraint *constraintFromMatrixRowFull(isl_int *row,
                                            __isl_take isl_space *Space) {
  isl_constraint *c;

  unsigned NbOut = isl_space_dim(Space, isl_dim_out);
  unsigned NbIn = isl_space_dim(Space, isl_dim_in);
  unsigned NbParam = isl_space_dim(Space, isl_dim_param);

  isl_local_space *LSpace = isl_local_space_from_space(Space);

  if (isl_int_is_zero(row[0]))
    c = isl_equality_alloc(LSpace);
  else
    c = isl_inequality_alloc(LSpace);

  unsigned current_column = 1;

  for (unsigned j = 0; j < NbOut; ++j)
    isl_constraint_set_coefficient(c, isl_dim_out, j, row[current_column++]);

  for (unsigned j = 0; j < NbIn; ++j)
    isl_constraint_set_coefficient(c, isl_dim_in, j, row[current_column++]);

  for (unsigned j = 0; j < NbParam; ++j)
    isl_constraint_set_coefficient(c, isl_dim_param, j, row[current_column++]);

  isl_constraint_set_constant(c, row[current_column]);

  return c;
}

/// @brief Create an isl map from a OpenScop matrix.
///
/// @param m The OpenScop matrix to translate.
/// @param Space The dimensions that are contained in the OpenScop matrix.
///
/// @return An isl map representing m.
isl_map *mapFromMatrix(scoplib_matrix_p m, __isl_take isl_space *Space) {
  isl_basic_map *bmap = isl_basic_map_universe(isl_space_copy(Space));

  for (unsigned i = 0; i < m->NbRows; ++i) {
    isl_constraint *c;

    c = constraintFromMatrixRowFull(m->p[i], isl_space_copy(Space));
    bmap = isl_basic_map_add_constraint(bmap, c);
  }

  isl_space_free(Space);

  return isl_map_from_basic_map(bmap);
}

/// @brief Create a new scattering for PollyStmt.
///
/// @param m The matrix describing the new scattering.
/// @param PollyStmt The statement to create the scattering for.
///
/// @return An isl_map describing the scattering.
isl_map *scatteringForStmt(scoplib_matrix_p m, ScopStmt *PollyStmt,
                           int scatteringDims) {

  unsigned NbParam = PollyStmt->getNumParams();
  unsigned NbIterators = PollyStmt->getNumIterators();
  unsigned NbScattering;

  if (scatteringDims == -1)
    NbScattering = m->NbColumns - 2 - NbParam - NbIterators;
  else
    NbScattering = scatteringDims;

  isl_ctx *ctx = PollyStmt->getParent()->getIslCtx();
  isl_space *Space = isl_dim_alloc(ctx, NbParam, NbIterators, NbScattering);

  isl_space *ParamSpace = PollyStmt->getParent()->getParamSpace();

  // We need to copy the isl_ids for the parameter dimensions to the new
  // map. Without doing this the current map would have different
  // ids then the new one, even though both are named identically.
  for (unsigned i = 0; i < isl_space_dim(Space, isl_dim_param); i++) {
    isl_id *id = isl_space_get_dim_id(ParamSpace, isl_dim_param, i);
    Space = isl_space_set_dim_id(Space, isl_dim_param, i, id);
  }

  isl_space_free(ParamSpace);

  Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering");
  Space = isl_space_set_tuple_id(Space, isl_dim_in, PollyStmt->getDomainId());

  if (scatteringDims == -1)
    return mapFromMatrix(m, Space);

  return mapFromMatrix(m, Space, scatteringDims);
}

unsigned maxScattering(scoplib_statement_p stmt) {
  unsigned max = 0;

  while (stmt) {
    max = std::max(max, stmt->schedule->NbRows);
    stmt = stmt->next;
  }

  return max;
}

typedef Dependences::StatementToIslMapTy StatementToIslMapTy;

void freeStmtToIslMap(StatementToIslMapTy *Map) {
  for (StatementToIslMapTy::iterator MI = Map->begin(), ME = Map->end();
       MI != ME; ++MI)
    isl_map_free(MI->second);

  delete (Map);
}

/// @brief Read the new scattering from the scoplib description.
///
/// @S      The Scop to update
/// @OScop  The ScopLib data structure describing the new scattering.
/// @return A map that contains for each Statement the new scattering.
StatementToIslMapTy *readScattering(Scop *S, scoplib_scop_p OScop) {
  StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy());

  scoplib_statement_p stmt = OScop->statement;

  // Check if we have dimensions for each scattering or if each row
  // represents a scattering dimension.
  int numScatteringDims = -1;
  ScopStmt *pollyStmt = *S->begin();

  if (stmt->schedule->NbColumns ==
      2 + pollyStmt->getNumParams() + pollyStmt->getNumIterators()) {
    numScatteringDims = maxScattering(stmt);
  }

  for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
    if (!stmt) {
      errs() << "Not enough statements available in OpenScop file\n";
      freeStmtToIslMap(&NewScattering);
      return NULL;
    }

    NewScattering[*SI] =
        scatteringForStmt(stmt->schedule, *SI, numScatteringDims);
    stmt = stmt->next;
  }

  if (stmt) {
    errs() << "Too many statements in OpenScop file\n";
    freeStmtToIslMap(&NewScattering);
    return NULL;
  }

  return &NewScattering;
}

/// @brief Update the scattering in a Scop using the scoplib description of
/// the scattering.
bool ScopLib::updateScattering() {
  if (!scoplib)
    return false;

  StatementToIslMapTy *NewScattering = readScattering(PollyScop, scoplib);

  if (!NewScattering)
    return false;

  if (!D->isValidScattering(NewScattering)) {
    freeStmtToIslMap(NewScattering);
    errs() << "OpenScop file contains a scattering that changes the "
           << "dependences. Use -disable-polly-legality to continue anyways\n";
    return false;
  }

  for (Scop::iterator SI = PollyScop->begin(), SE = PollyScop->end(); SI != SE;
       ++SI) {
    ScopStmt *Stmt = *SI;

    if (NewScattering->find(Stmt) != NewScattering->end())
      Stmt->setScattering(isl_map_copy((*NewScattering)[Stmt]));
  }

  freeStmtToIslMap(NewScattering);
  return true;
}
}

#endif
