coretypes.h: Include input.h and as-a.h.
[platform/upstream/gcc.git] / gcc / graphite-interchange.c
index aafb94a..7a51ca4 100644 (file)
@@ -1,7 +1,7 @@
 /* Interchange heuristics and transform for loop interchange on
    polyhedral representation.
 
-   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2009-2015 Free Software Foundation, Inc.
    Contributed by Sebastian Pop <sebastian.pop@amd.com> and
    Harsha Jagasia <harsha.jagasia@amd.com>.
 
@@ -20,37 +20,58 @@ 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/>.  */
+
 #include "config.h"
+
+#ifdef HAVE_isl
+#include <isl/aff.h>
+#include <isl/set.h>
+#include <isl/map.h>
+#include <isl/union_map.h>
+#include <isl/ilp.h>
+#include <isl/val.h>
+
+/* Since ISL-0.13, the extern is in val_gmp.h.  */
+#if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
+extern "C" {
+#endif
+#include <isl/val_gmp.h>
+#if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
+}
+#endif
+#endif
+
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "ggc.h"
+#include "alias.h"
+#include "symtab.h"
+#include "options.h"
 #include "tree.h"
-#include "rtl.h"
-#include "output.h"
+#include "fold-const.h"
+#include "predict.h"
+#include "tm.h"
+#include "hard-reg-set.h"
+#include "function.h"
+#include "dominance.h"
+#include "cfg.h"
 #include "basic-block.h"
-#include "diagnostic.h"
-#include "tree-flow.h"
-#include "tree-dump.h"
-#include "timevar.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "tree-ssa-loop.h"
+#include "dumpfile.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"
-#include "params.h"
-
-#ifdef HAVE_cloog
-#include "ppl_c.h"
 #include "sese.h"
-#include "graphite-ppl.h"
-#include "graphite.h"
+
+#ifdef HAVE_isl
 #include "graphite-poly.h"
 
+/* XXX isl rewrite following comment */
 /* Builds a linear expression, of dimension DIM, representing PDR's
    memory access:
 
@@ -68,87 +89,89 @@ along with GCC; see the file COPYING3.  If not see
    where the expression itself is:
    c_0 * s_0 + c_1 * s_1 + ... c_n * s_n.  */
 
-static ppl_Linear_Expression_t
-build_linearized_memory_access (ppl_dimension_type offset, poly_dr_p pdr)
+static isl_constraint *
+build_linearized_memory_access (isl_map *map, poly_dr_p pdr)
 {
-  ppl_Linear_Expression_t res;
-  ppl_Linear_Expression_t le;
-  ppl_dimension_type i;
-  ppl_dimension_type first = pdr_subscript_dim (pdr, 0);
-  ppl_dimension_type last = pdr_subscript_dim (pdr, PDR_NB_SUBSCRIPTS (pdr));
-  mpz_t size, sub_size;
-  graphite_dim_t dim = offset + pdr_dim (pdr);
-
-  ppl_new_Linear_Expression_with_dimension (&res, dim);
-
-  mpz_init (size);
-  mpz_set_si (size, 1);
-  mpz_init (sub_size);
-  mpz_set_si (sub_size, 1);
-
-  for (i = last - 1; i >= first; i--)
+  isl_constraint *res;
+  isl_local_space *ls = isl_local_space_from_space (isl_map_get_space (map));
+  unsigned offset, nsubs;
+  int i;
+  isl_ctx *ctx;
+
+  isl_val *size, *subsize, *size1;
+
+  res = isl_equality_alloc (ls);
+  ctx = isl_local_space_get_ctx (ls);
+  size = isl_val_int_from_ui (ctx, 1);
+
+  nsubs = isl_set_dim (pdr->extent, isl_dim_set);
+  /* -1 for the already included L dimension.  */
+  offset = isl_map_dim (map, isl_dim_out) - 1 - nsubs;
+  res = isl_constraint_set_coefficient_si (res, isl_dim_out, offset + nsubs, -1);
+  /* Go through all subscripts from last to first.  First dimension
+     is the alias set, ignore it.  */
+  for (i = nsubs - 1; i >= 1; i--)
     {
-      ppl_set_coef_gmp (res, i + offset, size);
-
-      ppl_new_Linear_Expression_with_dimension (&le, dim - offset);
-      ppl_set_coef (le, i, 1);
-      ppl_max_for_le_pointset (PDR_ACCESSES (pdr), le, sub_size);
-      mpz_mul (size, size, sub_size);
-      ppl_delete_Linear_Expression (le);
+      isl_space *dc;
+      isl_aff *aff;
+
+      size1 = isl_val_copy (size);
+      res = isl_constraint_set_coefficient_val (res, isl_dim_out, offset + i, size);
+      dc = isl_set_get_space (pdr->extent);
+      aff = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
+      aff = isl_aff_set_coefficient_si (aff, isl_dim_in, i, 1);
+      subsize = isl_set_max_val (pdr->extent, aff);
+      isl_aff_free (aff);
+      size = isl_val_mul (size1, subsize);
     }
 
-  mpz_clear (sub_size);
-  mpz_clear (size);
+  isl_val_free (size);
+
   return res;
 }
 
-/* Builds a partial difference equations and inserts them
-   into pointset powerset polyhedron P.  Polyhedron is assumed
-   to have the format: T|I|T'|I'|G|S|S'|l1|l2.
-
-   TIME_DEPTH is the time dimension w.r.t. which we are
-   differentiating.
-   OFFSET represents the number of dimensions between
-   columns t_{time_depth} and t'_{time_depth}.
-   DIM_SCTR is the number of scattering dimensions.  It is
-   essentially the dimensionality of the T vector.
-
-   The following equations are inserted into the polyhedron P:
-    | t_1 = t_1'
-    | ...
-    | t_{time_depth-1} = t'_{time_depth-1}
-    | t_{time_depth} = t'_{time_depth} + 1
-    | t_{time_depth+1} = t'_{time_depth + 1}
-    | ...
-    | t_{dim_sctr} = t'_{dim_sctr}.  */
+/* Set STRIDE to the stride of PDR in memory by advancing by one in
+   the loop at DEPTH.  */
 
 static void
-build_partial_difference (ppl_Pointset_Powerset_C_Polyhedron_t *p,
-                          ppl_dimension_type time_depth,
-                          ppl_dimension_type offset,
-                          ppl_dimension_type dim_sctr)
+pdr_stride_in_loop (mpz_t stride, graphite_dim_t depth, poly_dr_p pdr)
 {
-  ppl_Constraint_t new_cstr;
-  ppl_Linear_Expression_t le;
-  ppl_dimension_type i;
-  ppl_dimension_type dim;
-  ppl_Pointset_Powerset_C_Polyhedron_t temp;
+  poly_bb_p pbb = PDR_PBB (pdr);
+  isl_map *map;
+  isl_set *set;
+  isl_aff *aff;
+  isl_space *dc;
+  isl_constraint *lma, *c;
+  isl_val *islstride;
+  graphite_dim_t time_depth;
+  unsigned offset, nt;
+  unsigned i;
+  /* XXX isl rewrite following comments.  */
+  /* Builds a partial difference equations and inserts them
+     into pointset powerset polyhedron P.  Polyhedron is assumed
+     to have the format: T|I|T'|I'|G|S|S'|l1|l2.
+
+     TIME_DEPTH is the time dimension w.r.t. which we are
+     differentiating.
+     OFFSET represents the number of dimensions between
+     columns t_{time_depth} and t'_{time_depth}.
+     DIM_SCTR is the number of scattering dimensions.  It is
+     essentially the dimensionality of the T vector.
+
+     The following equations are inserted into the polyhedron P:
+     | t_1 = t_1'
+     | ...
+     | t_{time_depth-1} = t'_{time_depth-1}
+     | t_{time_depth} = t'_{time_depth} + 1
+     | t_{time_depth+1} = t'_{time_depth + 1}
+     | ...
+     | t_{dim_sctr} = t'_{dim_sctr}.  */
 
   /* Add the equality: t_{time_depth} = t'_{time_depth} + 1.
      This is the core part of this alogrithm, since this
      constraint asks for the memory access stride (difference)
      between two consecutive points in time dimensions.  */
 
-  ppl_Pointset_Powerset_C_Polyhedron_space_dimension (*p, &dim);
-  ppl_new_Linear_Expression_with_dimension (&le, dim);
-  ppl_set_coef (le, time_depth, 1);
-  ppl_set_coef (le, time_depth + offset, -1);
-  ppl_set_inhomogeneous (le, 1);
-  ppl_new_Constraint (&new_cstr, le, PPL_CONSTRAINT_TYPE_EQUAL);
-  ppl_Pointset_Powerset_C_Polyhedron_add_constraint (*p, new_cstr);
-  ppl_delete_Linear_Expression (le);
-  ppl_delete_Constraint (new_cstr);
-
   /* Add equalities:
      | t1 = t1'
      | ...
@@ -159,181 +182,92 @@ build_partial_difference (ppl_Pointset_Powerset_C_Polyhedron_t *p,
 
      This means that all the time dimensions are equal except for
      time_depth, where the constraint is t_{depth} = t'_{depth} + 1
-     step.  More to this: we should be carefull not to add equalities
+     step.  More to this: we should be careful not to add equalities
      to the 'coupled' dimensions, which happens when the one dimension
      is stripmined dimension, and the other dimension corresponds
      to the point loop inside stripmined dimension.  */
 
-  ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron (&temp, *p);
-
-  for (i = 0; i < dim_sctr; i++)
+  /* pdr->accesses:    [P1..nb_param,I1..nb_domain]->[a,S1..nb_subscript]
+          ??? [P] not used for PDRs?
+     pdr->extent:      [a,S1..nb_subscript]
+     pbb->domain:      [P1..nb_param,I1..nb_domain]
+     pbb->transformed: [P1..nb_param,I1..nb_domain]->[T1..Tnb_sctr]
+          [T] includes local vars (currently unused)
+     
+     First we create [P,I] -> [T,a,S].  */
+  
+  map = isl_map_flat_range_product (isl_map_copy (pbb->transformed),
+                                   isl_map_copy (pdr->accesses));
+  /* Add a dimension for L: [P,I] -> [T,a,S,L].*/
+  map = isl_map_add_dims (map, isl_dim_out, 1);
+  /* Build a constraint for "lma[S] - L == 0", effectively calculating
+     L in terms of subscripts.  */
+  lma = build_linearized_memory_access (map, pdr);
+  /* And add it to the map, so we now have:
+     [P,I] -> [T,a,S,L] : lma([S]) == L.  */
+  map = isl_map_add_constraint (map, lma);
+
+  /* Then we create  [P,I,P',I'] -> [T,a,S,L,T',a',S',L'].  */
+  map = isl_map_flat_product (map, isl_map_copy (map));
+
+  /* Now add the equality T[time_depth] == T'[time_depth]+1.  This will
+     force L' to be the linear address at T[time_depth] + 1. */
+  time_depth = psct_dynamic_dim (pbb, depth);
+  /* Length of [a,S] plus [L] ...  */
+  offset = 1 + isl_map_dim (pdr->accesses, isl_dim_out);
+  /* ... plus [T].  */
+  offset += isl_map_dim (pbb->transformed, isl_dim_out);
+
+  c = isl_equality_alloc (isl_local_space_from_space (isl_map_get_space (map)));
+  c = isl_constraint_set_coefficient_si (c, isl_dim_out, time_depth, 1);
+  c = isl_constraint_set_coefficient_si (c, isl_dim_out,
+                                        offset + time_depth, -1);
+  c = isl_constraint_set_constant_si (c, 1);
+  map = isl_map_add_constraint (map, c);
+
+  /* Now we equate most of the T/T' elements (making PITaSL nearly
+     the same is (PITaSL)', except for one dimension, namely for 'depth'
+     (an index into [I]), after translating to index into [T].  Take care
+     to not produce an empty map, which indicates we wanted to equate
+     two dimensions that are already coupled via the above time_depth
+     dimension.  Happens with strip mining where several scatter dimension
+     are interdependend.  */
+  /* Length of [T].  */
+  nt = pbb_nb_scattering_transform (pbb) + pbb_nb_local_vars (pbb);
+  for (i = 0; i < nt; i++)
     if (i != time_depth)
       {
-        ppl_new_Linear_Expression_with_dimension (&le, dim);
-        ppl_set_coef (le, i, 1);
-        ppl_set_coef (le, i + offset, -1);
-        ppl_new_Constraint (&new_cstr, le, PPL_CONSTRAINT_TYPE_EQUAL);
-        ppl_Pointset_Powerset_C_Polyhedron_add_constraint (temp, new_cstr);
-
-        if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (temp))
-          {
-            ppl_delete_Pointset_Powerset_C_Polyhedron (temp);
-            ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron (&temp, *p);
-          }
-        else
-          ppl_Pointset_Powerset_C_Polyhedron_add_constraint (*p, new_cstr);
-        ppl_delete_Linear_Expression (le);
-        ppl_delete_Constraint (new_cstr);
+       isl_map *temp = isl_map_equate (isl_map_copy (map),
+                                       isl_dim_out, i,
+                                       isl_dim_out, offset + i);
+       if (isl_map_is_empty (temp))
+         isl_map_free (temp);
+       else
+         {
+           isl_map_free (map);
+           map = temp;
+         }
       }
 
-  ppl_delete_Pointset_Powerset_C_Polyhedron (temp);
-}
-
-
-/* Set STRIDE to the stride of PDR in memory by advancing by one in
-   the loop at DEPTH.  */
-
-static void
-pdr_stride_in_loop (mpz_t stride, graphite_dim_t depth, poly_dr_p pdr)
-{
-  ppl_dimension_type time_depth;
-  ppl_Linear_Expression_t le, lma;
-  ppl_Constraint_t new_cstr;
-  ppl_dimension_type i, *map;
-  ppl_Pointset_Powerset_C_Polyhedron_t p1, p2, sctr;
-  graphite_dim_t nb_subscripts = PDR_NB_SUBSCRIPTS (pdr) + 1;
-  poly_bb_p pbb = PDR_PBB (pdr);
-  ppl_dimension_type offset = pbb_nb_scattering_transform (pbb)
-                              + pbb_nb_local_vars (pbb)
-                              + pbb_dim_iter_domain (pbb);
-  ppl_dimension_type offsetg = offset + pbb_nb_params (pbb);
-  ppl_dimension_type dim_sctr = pbb_nb_scattering_transform (pbb)
-                                + pbb_nb_local_vars (pbb);
-  ppl_dimension_type dim_L1 = offset + offsetg + 2 * nb_subscripts;
-  ppl_dimension_type dim_L2 = offset + offsetg + 2 * nb_subscripts + 1;
-  ppl_dimension_type new_dim = offset + offsetg + 2 * nb_subscripts + 2;
-
-  /* The resulting polyhedron should have the following format:
-     T|I|T'|I'|G|S|S'|l1|l2
-     where:
-     | T = t_1..t_{dim_sctr}
-     | I = i_1..i_{dim_iter_domain}
-     | T'= t'_1..t'_{dim_sctr}
-     | I'= i'_1..i'_{dim_iter_domain}
-     | G = g_1..g_{nb_params}
-     | S = s_1..s_{nb_subscripts}
-     | S'= s'_1..s'_{nb_subscripts}
-     | l1 and l2 are scalars.
-
-     Some invariants:
-     offset = dim_sctr + dim_iter_domain + nb_local_vars
-     offsetg = dim_sctr + dim_iter_domain + nb_local_vars + nb_params.  */
-
-  /* Construct the T|I|0|0|G|0|0|0|0 part.  */
-  {
-    ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
-      (&sctr, PBB_TRANSFORMED_SCATTERING (pbb));
-    ppl_Pointset_Powerset_C_Polyhedron_add_space_dimensions_and_embed
-      (sctr, 2 * nb_subscripts + 2);
-    ppl_insert_dimensions_pointset (sctr, offset, offset);
-  }
-
-  /* Construct the 0|I|0|0|G|S|0|0|0 part.  */
-  {
-    ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
-      (&p1, PDR_ACCESSES (pdr));
-    ppl_Pointset_Powerset_C_Polyhedron_add_space_dimensions_and_embed
-      (p1, nb_subscripts + 2);
-    ppl_insert_dimensions_pointset (p1, 0, dim_sctr);
-    ppl_insert_dimensions_pointset (p1, offset, offset);
-  }
-
-  /* Construct the 0|0|0|0|0|S|0|l1|0 part.  */
-  {
-    lma = build_linearized_memory_access (offset + dim_sctr, pdr);
-    ppl_set_coef (lma, dim_L1, -1);
-    ppl_new_Constraint (&new_cstr, lma, PPL_CONSTRAINT_TYPE_EQUAL);
-    ppl_Pointset_Powerset_C_Polyhedron_add_constraint (p1, new_cstr);
-    ppl_delete_Linear_Expression (lma);
-    ppl_delete_Constraint (new_cstr);
-  }
-
-  /* Now intersect all the parts to get the polyhedron P1:
-     T|I|0|0|G|0|0|0 |0
-     0|I|0|0|G|S|0|0 |0
-     0|0|0|0|0|S|0|l1|0
-     ------------------
-     T|I|0|0|G|S|0|l1|0.  */
-
-  ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (p1, sctr);
-  ppl_delete_Pointset_Powerset_C_Polyhedron (sctr);
-
-  /* Build P2, which would have the following form:
-     0|0|T'|I'|G|0|S'|0|l2
-
-     P2 is built, by remapping the P1 polyhedron:
-     T|I|0|0|G|S|0|l1|0
-
-     using the following mapping:
-     T->T'
-     I->I'
-     S->S'
-     l1->l2.  */
-  {
-    ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
-      (&p2, p1);
-
-    map = ppl_new_id_map (new_dim);
-
-    /* TI -> T'I'.  */
-    for (i = 0; i < offset; i++)
-      ppl_interchange (map, i, i + offset);
-
-    /* l1 -> l2.  */
-    ppl_interchange (map, dim_L1, dim_L2);
-
-    /* S -> S'.  */
-    for (i = 0; i < nb_subscripts; i++)
-      ppl_interchange (map, offset + offsetg + i,
-                      offset + offsetg + nb_subscripts + i);
-
-    ppl_Pointset_Powerset_C_Polyhedron_map_space_dimensions (p2, map, new_dim);
-    free (map);
-  }
-
-  time_depth = psct_dynamic_dim (pbb, depth);
-
-  /* P1 = P1 inter P2.  */
-  ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (p1, p2);
-  build_partial_difference (&p1, time_depth, offset, dim_sctr);
-
-  /* Maximise the expression L2 - L1.  */
-  {
-    ppl_new_Linear_Expression_with_dimension (&le, new_dim);
-    ppl_set_coef (le, dim_L2, 1);
-    ppl_set_coef (le, dim_L1, -1);
-    ppl_max_for_le_pointset (p1, le, stride);
-  }
+  /* Now maximize the expression L' - L.  */
+  set = isl_map_range (map);
+  dc = isl_set_get_space (set);
+  aff = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
+  aff = isl_aff_set_coefficient_si (aff, isl_dim_in, offset - 1, -1);
+  aff = isl_aff_set_coefficient_si (aff, isl_dim_in, offset + offset - 1, 1);
+  islstride = isl_set_max_val (set, aff);
+  isl_val_get_num_gmp (islstride, stride);
+  isl_val_free (islstride);
+  isl_aff_free (aff);
+  isl_set_free (set);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
-      char *str;
-      void (*gmp_free) (void *, size_t);
-
-      fprintf (dump_file, "\nStride in BB_%d, DR_%d, depth %d:",
-              pbb_index (pbb), PDR_ID (pdr), (int) depth);
-      str = mpz_get_str (0, 10, stride);
-      fprintf (dump_file, "  %s ", str);
-      mp_get_memory_functions (NULL, NULL, &gmp_free);
-      (*gmp_free) (str, strlen (str) + 1);
+      gmp_fprintf (dump_file, "\nStride in BB_%d, DR_%d, depth %d:  %Zd ",
+                  pbb_index (pbb), PDR_ID (pdr), (int) depth, stride);
     }
-
-  ppl_delete_Pointset_Powerset_C_Polyhedron (p1);
-  ppl_delete_Pointset_Powerset_C_Polyhedron (p2);
-  ppl_delete_Linear_Expression (le);
 }
 
-
 /* Sets STRIDES to the sum of all the strides of the data references
    accessed in LOOP at DEPTH.  */
 
@@ -348,11 +282,11 @@ memory_strides_in_loop_1 (lst_p loop, graphite_dim_t depth, mpz_t strides)
   mpz_init (s);
   mpz_init (n);
 
-  FOR_EACH_VEC_ELT (lst_p, LST_SEQ (loop), j, l)
+  FOR_EACH_VEC_ELT (LST_SEQ (loop), j, l)
     if (LST_LOOP_P (l))
       memory_strides_in_loop_1 (l, depth, strides);
     else
-      FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (LST_PBB (l)), i, pdr)
+      FOR_EACH_VEC_ELT (PBB_DRS (LST_PBB (l)), i, pdr)
        {
          pdr_stride_in_loop (s, depth, pdr);
          mpz_set_si (n, PDR_NB_REFS (pdr));
@@ -461,20 +395,18 @@ memory_strides_in_loop (lst_p loop, graphite_dim_t depth, mpz_t strides)
    profitable to interchange the loops at DEPTH1 and DEPTH2.  */
 
 static bool
-lst_interchange_profitable_p (lst_p loop1, lst_p loop2)
+lst_interchange_profitable_p (lst_p nest, int depth1, int depth2)
 {
   mpz_t d1, d2;
   bool res;
 
-  gcc_assert (loop1 && loop2
-             && LST_LOOP_P (loop1) && LST_LOOP_P (loop2)
-             && lst_depth (loop1) < lst_depth (loop2));
+  gcc_assert (depth1 < depth2);
 
   mpz_init (d1);
   mpz_init (d2);
 
-  memory_strides_in_loop (loop1, lst_depth (loop1), d1);
-  memory_strides_in_loop (loop2, lst_depth (loop2), d2);
+  memory_strides_in_loop (nest, depth1, d1);
+  memory_strides_in_loop (nest, depth2, d2);
 
   res = mpz_cmp (d1, d2) < 0;
 
@@ -492,23 +424,23 @@ static void
 pbb_interchange_loop_depths (graphite_dim_t depth1, graphite_dim_t depth2,
                             poly_bb_p pbb)
 {
-  ppl_dimension_type i, dim;
-  ppl_dimension_type *map;
-  ppl_Polyhedron_t poly = PBB_TRANSFORMED_SCATTERING (pbb);
-  ppl_dimension_type dim1 = psct_dynamic_dim (pbb, depth1);
-  ppl_dimension_type dim2 = psct_dynamic_dim (pbb, depth2);
-
-  ppl_Polyhedron_space_dimension (poly, &dim);
-  map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim);
-
-  for (i = 0; i < dim; i++)
-    map[i] = i;
-
-  map[dim1] = dim2;
-  map[dim2] = dim1;
-
-  ppl_Polyhedron_map_space_dimensions (poly, map, dim);
-  free (map);
+  unsigned i;
+  unsigned dim1 = psct_dynamic_dim (pbb, depth1);
+  unsigned dim2 = psct_dynamic_dim (pbb, depth2);
+  isl_space *d = isl_map_get_space (pbb->transformed);
+  isl_space *d1 = isl_space_range (d);
+  unsigned n = isl_space_dim (d1, isl_dim_out);
+  isl_space *d2 = isl_space_add_dims (d1, isl_dim_in, n);
+  isl_map *x = isl_map_universe (d2);
+
+  x = isl_map_equate (x, isl_dim_in, dim1, isl_dim_out, dim2);
+  x = isl_map_equate (x, isl_dim_in, dim2, isl_dim_out, dim1);
+
+  for (i = 0; i < n; i++)
+    if (i != dim1 && i != dim2)
+      x = isl_map_equate (x, isl_dim_in, i, isl_dim_out, i);
+
+  pbb->transformed = isl_map_apply_range (pbb->transformed, x);
 }
 
 /* Apply the interchange of loops at depths DEPTH1 and DEPTH2 to all
@@ -525,7 +457,7 @@ lst_apply_interchange (lst_p lst, int depth1, int depth2)
       int i;
       lst_p l;
 
-      FOR_EACH_VEC_ELT (lst_p, LST_SEQ (lst), i, l)
+      FOR_EACH_VEC_ELT (LST_SEQ (lst), i, l)
        lst_apply_interchange (l, depth1, depth2);
     }
   else
@@ -544,8 +476,8 @@ lst_perfectly_nested_p (lst_p loop1, lst_p loop2)
   if (!LST_LOOP_P (loop1))
     return false;
 
-  return VEC_length (lst_p, LST_SEQ (loop1)) == 1
-    && lst_perfectly_nested_p (VEC_index (lst_p, LST_SEQ (loop1), 0), loop2);
+  return LST_SEQ (loop1).length () == 1
+         && lst_perfectly_nested_p (LST_SEQ (loop1)[0], loop2);
 }
 
 /* Transform the loop nest between LOOP1 and LOOP2 into a perfect
@@ -607,12 +539,12 @@ lst_try_interchange_loops (scop_p scop, lst_p loop1, lst_p loop2)
 
   lst_p before = NULL, nest = NULL, after = NULL;
 
-  if (!lst_interchange_profitable_p (loop1, loop2))
-    return false;
-
   if (!lst_perfectly_nested_p (loop1, loop2))
     lst_perfect_nestify (loop1, loop2, &before, &nest, &after);
 
+  if (!lst_interchange_profitable_p (loop2, depth1, depth2))
+    return false;
+
   lst_apply_interchange (loop2, depth1, depth2);
 
   /* Sync the transformed LST information and the PBB scatterings
@@ -665,13 +597,13 @@ lst_interchange_select_inner (scop_p scop, lst_p outer_father, int outer,
 
   gcc_assert (outer_father
              && LST_LOOP_P (outer_father)
-             && LST_LOOP_P (VEC_index (lst_p, LST_SEQ (outer_father), outer))
+             && LST_LOOP_P (LST_SEQ (outer_father)[outer])
              && inner_father
              && LST_LOOP_P (inner_father));
 
-  loop1 = VEC_index (lst_p, LST_SEQ (outer_father), outer);
+  loop1 = LST_SEQ (outer_father)[outer];
 
-  FOR_EACH_VEC_ELT (lst_p, LST_SEQ (inner_father), inner, loop2)
+  FOR_EACH_VEC_ELT (LST_SEQ (inner_father), inner, loop2)
     if (LST_LOOP_P (loop2)
        && (lst_try_interchange_loops (scop, loop1, loop2)
            || lst_interchange_select_inner (scop, outer_father, outer, loop2)))
@@ -681,45 +613,46 @@ lst_interchange_select_inner (scop_p scop, lst_p outer_father, int outer,
 }
 
 /* Interchanges all the loops of LOOP and the loops of its body that
-   are considered profitable to interchange.  Return true if it did
-   interchanged some loops.  OUTER is the index in LST_SEQ (LOOP) that
+   are considered profitable to interchange.  Return the number of
+   interchanged loops.  OUTER is the index in LST_SEQ (LOOP) that
    points to the next outer loop to be considered for interchange.  */
 
-static bool
+static int
 lst_interchange_select_outer (scop_p scop, lst_p loop, int outer)
 {
   lst_p l;
-  bool res = false;
+  int res = 0;
   int i = 0;
   lst_p father;
 
   if (!loop || !LST_LOOP_P (loop))
-    return false;
+    return 0;
 
   father = LST_LOOP_FATHER (loop);
   if (father)
     {
       while (lst_interchange_select_inner (scop, father, outer, loop))
        {
-         res = true;
-         loop = VEC_index (lst_p, LST_SEQ (father), outer);
+         res++;
+         loop = LST_SEQ (father)[outer];
        }
     }
 
   if (LST_LOOP_P (loop))
-    FOR_EACH_VEC_ELT (lst_p, LST_SEQ (loop), i, l)
+    FOR_EACH_VEC_ELT (LST_SEQ (loop), i, l)
       if (LST_LOOP_P (l))
-       res |= lst_interchange_select_outer (scop, l, i);
+       res += lst_interchange_select_outer (scop, l, i);
 
   return res;
 }
 
-/* Interchanges all the loop depths that are considered profitable for SCOP.  */
+/* Interchanges all the loop depths that are considered profitable for
+   SCOP.  Return the number of interchanged loops.  */
 
-bool
+int
 scop_do_interchange (scop_p scop)
 {
-  bool res = lst_interchange_select_outer
+  int res = lst_interchange_select_outer
     (scop, SCOP_TRANSFORMED_SCHEDULE (scop), 0);
 
   lst_update_scattering (SCOP_TRANSFORMED_SCHEDULE (scop));