//===- 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 "stdio.h"
#include "isl/set.h"
#include "isl/map.h"
#include "isl/constraint.h"
#include "isl/val_gmp.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 (ScopStmt *Stmt : *PollyScop)
    for (MemoryAccess *MA : *Stmt) {
      const Value *BaseAddr = MA->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);
  stmt->getBasicBlock()->printAsOperand(OS, 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 = nullptr;

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

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

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

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

  free(stmt->iterators);
  stmt->iterators = nullptr;
  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_val *v;

  // Assign variables
  for (int i = 0; i < nb_vars; ++i) {
    v = isl_constraint_get_coefficient_val(c, isl_dim_set, i);
    SCOPVAL_init(vec->p[i + 1]);
    isl_val_get_num_gmp(v, vec->p[i + 1]);
    isl_val_free(v);
  }

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

  // Assign constant
  v = isl_constraint_get_constant_val(c);
  SCOPVAL_init(vec->p[nb_params + nb_vars + 1]);
  isl_val_get_num_gmp(v, vec->p[nb_params + nb_vars + 1]);

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

  scoplib_vector_free(vec);
  isl_constraint_free(c);
  isl_val_free(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_val *v;

  // Assign variables
  for (int i = 0; i < nb_in; ++i) {
    v = isl_constraint_get_coefficient_val(c, isl_dim_in, i);
    SCOPVAL_init(vec->p[i + 1]);
    isl_val_get_num_gmp(v, vec->p[i + 1]);
    isl_val_free(v);
  }

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

  // Assign constant
  v = isl_constraint_get_constant_val(c);
  SCOPVAL_init(vec->p[nb_in + nb_params + 1]);
  isl_val_get_num_gmp(v, vec->p[nb_in + nb_params + 1]);

  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);

  scoplib_vector_free(null);
  scoplib_vector_free(vec);
  isl_constraint_free(c);
  isl_val_free(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_val *v;

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

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

    if (inverse)
      v = isl_val_neg(v);

    SCOPVAL_init(vec->p[i + 1]);
    isl_val_get_num_gmp(v, vec->p[i + 1]);
    isl_val_free(v);
  }

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

    if (inverse)
      v = isl_val_neg(v);

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

  // Assign constant
  v = isl_constraint_get_constant_val(c);

  if (inverse)
    v = isl_val_neg(v);

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

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

  scoplib_vector_free(vec);
  isl_constraint_free(c);
  isl_val_free(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 (MemoryAccess *MA : *S)
    if (MA->isRead() == isRead) {
      // Extract the access function.
      isl_map *AccessRelation = MA->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(MA->getBaseAddr());
      SCOPVAL_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 = nullptr;
  scoplib->nb_arrays = 0;

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

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

  scoplib_statement_p stmt = scoplib->statement;

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

  scoplib->statement = nullptr;

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

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

  if (SCOPVAL_zero_p(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;

  isl_val *v;

  for (unsigned j = 0; j < NbIn; ++j) {
    v = isl_val_int_from_gmp(ctx, row[current_column++]);
    c = isl_constraint_set_coefficient_val(c, isl_dim_in, j, v);
  }

  for (unsigned j = 0; j < NbParam; ++j) {
    v = isl_val_int_from_gmp(ctx, row[current_column++]);
    c = isl_constraint_set_coefficient_val(c, isl_dim_param, j, v);
  }

  v = isl_val_int_from_gmp(ctx, row[current_column]);
  c = isl_constraint_set_constant_val(c, v);

  return c;
}

/// @brief Create an isl map from a ScopLib matrix.
///
/// @param m The ScopLib matrix to translate.
/// @param Space The dimensions that are contained in the ScopLib 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));
    c = isl_constraint_set_coefficient_si(c, isl_dim_out, i, -1);
    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)));
    c = isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1);
    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 ScopLib integers.
///
/// @param row An array of isl/ScopLib integers.
/// @param Space An isl space object, describing how to spilt the dimensions.
///
/// @return An isl constraint representing this integer array.
isl_constraint *constraintFromMatrixRowFull(mpz_t *row,
                                            __isl_take isl_space *Space) {
  isl_constraint *c;
  isl_ctx *ctx = isl_space_get_ctx(Space);

  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 (SCOPVAL_zero_p(row[0]))
    c = isl_equality_alloc(LSpace);
  else
    c = isl_inequality_alloc(LSpace);

  unsigned current_column = 1;

  isl_val *v;

  for (unsigned j = 0; j < NbOut; ++j) {
    v = isl_val_int_from_gmp(ctx, row[current_column++]);
    c = isl_constraint_set_coefficient_val(c, isl_dim_out, j, v);
  }

  for (unsigned j = 0; j < NbIn; ++j) {
    v = isl_val_int_from_gmp(ctx, row[current_column++]);
    c = isl_constraint_set_coefficient_val(c, isl_dim_in, j, v);
  }

  for (unsigned j = 0; j < NbParam; ++j) {
    v = isl_val_int_from_gmp(ctx, row[current_column++]);
    c = isl_constraint_set_coefficient_val(c, isl_dim_param, j, v);
  }

  v = isl_val_int_from_gmp(ctx, row[current_column]);
  c = isl_constraint_set_constant_val(c, v);

  return c;
}

/// @brief Create an isl map from a ScopLib matrix.
///
/// @param m The ScopLib matrix to translate.
/// @param Space The dimensions that are contained in the ScopLib 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 ScopLib file\n";
      freeStmtToIslMap(&NewScattering);
      return nullptr;
    }

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

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

  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() << "ScopLib 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
