[llvm-commits] [polly] r134181 - in /polly/trunk: include/polly/Support/GICHelper.h lib/ScheduleOptimizer.cpp lib/Support/GICHelper.cpp

Tobias Grosser grosser at fim.uni-passau.de
Thu Jun 30 13:01:02 PDT 2011


Author: grosser
Date: Thu Jun 30 15:01:02 2011
New Revision: 134181

URL: http://llvm.org/viewvc/llvm-project?rev=134181&view=rev
Log:
ScheduleOpt: Use band forest to get the schedules

isl introduced a new representation for the schedules it calculates. The new
representation uses a forest of bands and is closer to the structure of the
data as the old interface. Switch to the new interface, as it is nicer to use
and as the old interface will soon be removed from isl.

WARNING: This commit needs a version of isl that is more recent that the one
         included in CLooG. See:
	 http://polly.grosser.es/get_started.html#islTrunk

Modified:
    polly/trunk/include/polly/Support/GICHelper.h
    polly/trunk/lib/ScheduleOptimizer.cpp
    polly/trunk/lib/Support/GICHelper.cpp

Modified: polly/trunk/include/polly/Support/GICHelper.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/GICHelper.h?rev=134181&r1=134180&r2=134181&view=diff
==============================================================================
--- polly/trunk/include/polly/Support/GICHelper.h (original)
+++ polly/trunk/include/polly/Support/GICHelper.h Thu Jun 30 15:01:02 2011
@@ -21,6 +21,7 @@
 struct isl_union_map;
 struct isl_set;
 struct isl_union_set;
+struct isl_schedule;
 
 namespace polly {
 
@@ -41,6 +42,8 @@
 std::string stringFromIslObj(/*__isl_keep*/ isl_union_map *umap);
 std::string stringFromIslObj(/*__isl_keep*/ isl_set *set);
 std::string stringFromIslObj(/*__isl_keep*/ isl_union_set *uset);
+std::string stringFromIslObj(/*__isl_keep*/ isl_schedule *schedule);
+
 //@}
 } //end namespace polly
 

Modified: polly/trunk/lib/ScheduleOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/ScheduleOptimizer.cpp?rev=134181&r1=134180&r2=134181&view=diff
==============================================================================
--- polly/trunk/lib/ScheduleOptimizer.cpp (original)
+++ polly/trunk/lib/ScheduleOptimizer.cpp Thu Jun 30 15:01:02 2011
@@ -20,6 +20,7 @@
 #include "polly/Cloog.h"
 #include "polly/LinkAllPasses.h"
 
+#include "polly/Support/GICHelper.h"
 #include "polly/Dependences.h"
 #include "polly/ScopInfo.h"
 
@@ -27,6 +28,7 @@
 #include "isl/map.h"
 #include "isl/constraint.h"
 #include "isl/schedule.h"
+#include "isl/band.h"
 
 #define DEBUG_TYPE "polly-optimize-isl"
 #include "llvm/Support/Debug.h"
@@ -91,57 +93,154 @@
   }
 }
 
-// @brief Tile a band.
+// getTileMap - Create a map that describes a n-dimensonal tiling.
 //
-// This function recieves a map that assigns to the instances of a statement
-// an execution time.
+// getTileMap creates a map from a n-dimensional scattering space into an
+// 2*n-dimensional scattering space. The map describes a rectangular tiling.
 //
-// [i_0, i_1, i_2] -> [o_0, o_1, o_2, i_0, i_1, i_2]:
-//   o_0 % 32 = 0 and o_1 % 32 = 0 and o_2 % 32 = 0
-//   and o0 <= i0 <= o0 + 32 and o1 <= i1 <= o1 + 32 and o2 <= i2 <= o2 + 32
-
-static isl_map *tileBand(isl_map *band) {
-  int dimensions = isl_map_n_out(band);
-  int tileSize = 32;
-
-  isl_dim *dim = isl_dim_alloc(isl_map_get_ctx(band), isl_map_n_param(band),
-                               dimensions, dimensions * 3);
-  isl_basic_map *tiledBand = isl_basic_map_universe(isl_dim_copy(dim));
-
-  for (int i = 0; i < dimensions; i++) {
-    isl_constraint *c = isl_equality_alloc(isl_dim_copy(dim));
-    isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1);
-    isl_constraint_set_coefficient_si(c, isl_dim_out, 2 * dimensions + i,
-                                      -tileSize);
-    tiledBand = isl_basic_map_add_constraint(tiledBand, c);
+// Example:
+//   scheduleDimensions = 2, parameterDimensions = 1, tileSize = 32
+//
+//   tileMap := [p0] -> {[s0, s1] -> [t0, t1, s0, s1]:
+//                        t0 % 32 = 0 and t0 <= s0 < t0 + 32 and
+//                        t1 % 32 = 0 and t1 <= s1 < t1 + 32}
+//
+//  Before tiling:
+//
+//  for (i = 0; i < N; i++)
+//    for (j = 0; j < M; j++)
+//	S(i,j)
+//
+//  After tiling:
+//
+//  for (t_i = 0; t_i < N; i+=32)
+//    for (t_j = 0; t_j < M; j+=32)
+//	for (i = t_i; i < min(t_i + 32, N); i++)  | Unknown that N % 32 = 0
+//	  for (j = t_j; j < t_j + 32; j++)        |   Known that M % 32 = 0
+//	    S(i,j)
+//
+static isl_basic_map *getTileMap(isl_ctx *ctx, int scheduleDimensions,
+				 int parameterDimensions, int tileSize = 32) {
+  // We construct
+  //
+  // tileMap := [p0] -> {[s0, s1] -> [t0, t1, p0, p1, a0, a1]:
+  //	                  s0 = a0 * 32 and s0 = p0 and t0 <= p0 < t0 + 32 and
+  //	                  s1 = a1 * 32 and s1 = p1 and t1 <= p1 < t1 + 32}
+  //
+  // and project out the auxilary dimensions a0 and a1.
+  isl_dim *dim = isl_dim_alloc(ctx, parameterDimensions, scheduleDimensions,
+			       scheduleDimensions * 3);
+  isl_basic_map *tileMap = isl_basic_map_universe(isl_dim_copy(dim));
+
+  for (int x = 0; x < scheduleDimensions; x++) {
+    int sX = x;
+    int tX = x;
+    int pX = scheduleDimensions + x;
+    int aX = 2 * scheduleDimensions + x;
+
+    isl_constraint *c;
 
+    // sX = aX * tileSize;
+    c = isl_equality_alloc(isl_dim_copy(dim));
+    isl_constraint_set_coefficient_si(c, isl_dim_out, sX, 1);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, aX, -tileSize);
+    tileMap = isl_basic_map_add_constraint(tileMap, c);
 
+    // pX = sX;
     c = isl_equality_alloc(isl_dim_copy(dim));
-    isl_constraint_set_coefficient_si(c, isl_dim_in, i, -1);
-    isl_constraint_set_coefficient_si(c, isl_dim_out, dimensions + i, 1);
-    tiledBand = isl_basic_map_add_constraint(tiledBand, c);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, pX, 1);
+    isl_constraint_set_coefficient_si(c, isl_dim_in, sX, -1);
+    tileMap = isl_basic_map_add_constraint(tileMap, c);
 
+    // tX <= pX
     c = isl_inequality_alloc(isl_dim_copy(dim));
-    isl_constraint_set_coefficient_si(c, isl_dim_out, i, -1);
-    isl_constraint_set_coefficient_si(c, isl_dim_out, dimensions + i, 1);
-    tiledBand = isl_basic_map_add_constraint(tiledBand, c);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, pX, 1);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, tX, -1);
+    tileMap = isl_basic_map_add_constraint(tileMap, c);
 
+    // pX <= tX + (tileSize - 1)
     c = isl_inequality_alloc(isl_dim_copy(dim));
-    isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1);
-    isl_constraint_set_coefficient_si(c, isl_dim_out, dimensions + i, -1);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, tX, 1);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, pX, -1);
     isl_constraint_set_constant_si(c, tileSize - 1);
-    tiledBand = isl_basic_map_add_constraint(tiledBand, c);
+    tileMap = isl_basic_map_add_constraint(tileMap, c);
   }
 
-  // Project out auxilary dimensions (introduced to ensure 'ii % tileSize = 0')
+  // Project out auxilary dimensions.
   //
-  // The real dimensions are transformed into existentially quantified ones.
-  // This reduces the number of visible scattering dimensions.  Also, Cloog
-  // produces better code, if auxilary dimensions are existentially quantified.
-  tiledBand = isl_basic_map_project_out(tiledBand, isl_dim_out, 2 * dimensions,
-                                        dimensions);
+  // The auxilary dimensions are transformed into existentially quantified ones.
+  // This reduces the number of visible scattering dimensions and allows Cloog
+  // to produces better code.
+  tileMap = isl_basic_map_project_out(tileMap, isl_dim_out,
+				      2 * scheduleDimensions,
+				      scheduleDimensions);
+  isl_dim_free(dim);
+  return tileMap;
+}
+
+isl_union_map *getTiledPartialSchedule(isl_band *band) {
+  isl_union_map *partialSchedule;
+  int scheduleDimensions, parameterDimensions;
+  isl_ctx *ctx;
+  isl_dim *dim;
+  isl_basic_map *tileMap;
+  isl_union_map *tileUnionMap;
+
+  partialSchedule = isl_band_get_partial_schedule(band);
+  ctx = isl_union_map_get_ctx(partialSchedule);
+  dim = isl_union_map_get_dim(partialSchedule);
+  scheduleDimensions = isl_band_n_member(band);
+  parameterDimensions = isl_dim_size(dim, isl_dim_param);
+
+  tileMap = getTileMap(ctx, scheduleDimensions, parameterDimensions);
+  tileUnionMap = isl_union_map_from_map(isl_map_from_basic_map(tileMap));
+
+  partialSchedule = isl_union_map_apply_range(partialSchedule, tileUnionMap);
+
+  isl_dim_free(dim);
+  isl_ctx_free(ctx);
+
+  return partialSchedule;
+}
+
+// tileBandList - Tile all bands contained in a band forest.
+//
+// Recursively walk the band forest and tile all bands in the forest. Return
+// a schedule that describes the tiled scattering.
+static isl_union_map *tileBandList(isl_band_list *blist) {
+  int numBands = isl_band_list_n_band(blist);
+
+  isl_union_map *finalSchedule = 0;
+
+  for (int i = 0; i < numBands; i++) {
+    isl_band *band;
+    isl_union_map *partialSchedule;
+    band = isl_band_list_get_band(blist, i);
+    partialSchedule = getTiledPartialSchedule(band);
+
+    if (isl_band_has_children(band)) {
+      isl_band_list *children = isl_band_get_children(band);
+      isl_union_map *suffixSchedule = tileBandList(children);
+      partialSchedule = isl_union_map_flat_range_product(partialSchedule,
+							 suffixSchedule);
+    }
+
+    if (finalSchedule)
+      isl_union_map_union(finalSchedule, partialSchedule);
+    else
+      finalSchedule = partialSchedule;
+
+    isl_band_free(band);
+  }
 
-  return isl_map_apply_range(band, isl_map_from_basic_map(tiledBand));
+  return finalSchedule;
+}
+
+static isl_union_map *tileSchedule(isl_schedule *schedule) {
+  isl_band_list *blist = isl_schedule_get_band_forest(schedule);
+  isl_union_map *tiledSchedule = tileBandList(blist);
+  isl_band_list_free(blist);
+  return tiledSchedule;
 }
 
 bool ScheduleOptimizer::runOnScop(Scop &S) {
@@ -179,57 +278,36 @@
 
   schedule  = isl_union_set_compute_schedule(domain, validity, proximity);
 
-  // Get the complete schedule.
-  isl_union_map *scheduleMap = isl_schedule_get_map(schedule);
-
   DEBUG(dbgs() << "Computed schedule: ");
-  DEBUG(isl_union_map_dump(scheduleMap));
+  DEBUG(dbgs() << stringFromIslObj(schedule));
   DEBUG(dbgs() << "Individual bands: ");
 
-  // Get individual tileable bands.
-  for (int i = 0; i <  isl_schedule_n_band(schedule); i++) {
-    isl_union_map *band = isl_schedule_get_band(schedule, i);
-
-    DEBUG(dbgs() << "Band " << i << ": ");
-    DEBUG(isl_union_map_dump(band));
-
-    for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) {
-      ScopStmt *stmt = *SI;
-
-      if (stmt->isFinalRead())
-        continue;
-
-      isl_set *domain = stmt->getDomain();
-      isl_union_map *stmtBand;
-      stmtBand = isl_union_map_intersect_domain(isl_union_map_copy(band),
-                                                isl_union_set_from_set(domain));
-
-      isl_map *sband;
-      isl_union_map_foreach_map(stmtBand, getSingleMap, &sband);
-
-      sband = tileBand(sband);
-      DEBUG(dbgs() << "tiled band: ");
-      DEBUG(isl_map_dump(sband));
-
-      if (i == 0)
-        stmt->setScattering(sband);
-      else {
-        isl_map *scattering = stmt->getScattering();
-        scattering = isl_map_range_product(scattering, sband);
-        scattering = isl_map_flatten(scattering);
-        stmt->setScattering(scattering);
-      }
-    }
+  isl_union_map *tiledSchedule = tileSchedule(schedule);
 
+  for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) {
+    ScopStmt *stmt = *SI;
+
+    if (stmt->isFinalRead())
+      continue;
+
+    isl_set *domain = stmt->getDomain();
+    isl_union_map *stmtBand;
+    stmtBand = isl_union_map_intersect_domain(isl_union_map_copy(tiledSchedule),
+					      isl_union_set_from_set(domain));
+    isl_map *stmtSchedule;
+    isl_union_map_foreach_map(stmtBand, getSingleMap, &stmtSchedule);
+    stmt->setScattering(stmtSchedule);
   }
 
+  isl_union_map_free(tiledSchedule);
+  isl_schedule_free(schedule);
+
   unsigned maxScatDims = 0;
 
   for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI)
     maxScatDims = std::max(isl_map_n_out((*SI)->getScattering()), maxScatDims);
 
   extendScattering(S, maxScatDims);
-  isl_schedule_free(schedule);
   return false;
 }
 

Modified: polly/trunk/lib/Support/GICHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/GICHelper.cpp?rev=134181&r1=134180&r2=134181&view=diff
==============================================================================
--- polly/trunk/lib/Support/GICHelper.cpp (original)
+++ polly/trunk/lib/Support/GICHelper.cpp Thu Jun 30 15:01:02 2011
@@ -16,6 +16,7 @@
 #include "isl/union_set.h"
 #include "isl/map.h"
 #include "isl/union_map.h"
+#include "isl/schedule.h"
 
 using namespace llvm;
 
@@ -89,3 +90,12 @@
   isl_printer_free(p);
   return string;
 }
+
+std::string polly::stringFromIslObj(/*__isl_keep*/ isl_schedule *schedule) {
+  isl_ctx *ctx = isl_union_map_get_ctx(isl_schedule_get_map(schedule));
+  isl_printer *p = isl_printer_to_str(ctx);
+  isl_printer_print_schedule(p, schedule);
+  std::string string(isl_printer_get_str(p));
+  isl_printer_free(p);
+  return string;
+}





More information about the llvm-commits mailing list