[llvm-commits] [polly] r146028 - /polly/trunk/lib/ScheduleOptimizer.cpp
Tobias Grosser
grosser at fim.uni-passau.de
Tue Dec 6 23:42:57 PST 2011
Author: grosser
Date: Wed Dec 7 01:42:57 2011
New Revision: 146028
URL: http://llvm.org/viewvc/llvm-project?rev=146028&view=rev
Log:
ScheduleOptimizer: Rewrite getPrevectorMap to use isl_pw_aff
This increases the readablity. This also adds some comments that explain
what this function does.
Modified:
polly/trunk/lib/ScheduleOptimizer.cpp
Modified: polly/trunk/lib/ScheduleOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/ScheduleOptimizer.cpp?rev=146028&r1=146027&r2=146028&view=diff
==============================================================================
--- polly/trunk/lib/ScheduleOptimizer.cpp (original)
+++ polly/trunk/lib/ScheduleOptimizer.cpp Wed Dec 7 01:42:57 2011
@@ -26,6 +26,7 @@
#include "polly/Dependences.h"
#include "polly/ScopInfo.h"
+#include "isl/aff.h"
#include "isl/space.h"
#include "isl/map.h"
#include "isl/constraint.h"
@@ -223,68 +224,107 @@
return isl_union_map_apply_range(PartialSchedule, TileUMap);
}
-static isl_map *getPrevectorMap(isl_ctx *ctx, int vectorDimension,
- int scheduleDimensions,
- int parameterDimensions,
- int vectorWidth = 4) {
- assert (0 <= vectorDimension && vectorDimension < scheduleDimensions);
-
- isl_space *Space = isl_space_alloc(ctx, parameterDimensions,
- scheduleDimensions, scheduleDimensions + 2);
- isl_basic_map *tilingMap = isl_basic_map_universe(isl_space_copy(Space));
-
+// Create a map that pre-vectorizes one scheduling dimension.
+//
+// getPrevectorMap creates a map that maps each input dimension to the same
+// output dimension, except for the dimension DimToVectorize. DimToVectorize is
+// strip mined by 'VectorWidth' and the newly created point loop of
+// DimToVectorize is moved to the innermost level.
+//
+// Example (DimToVectorize=0, ScheduleDimensions=2, VectorWidth=4):
+//
+// | Before transformation
+// |
+// | A[i,j] -> [i,j]
+// |
+// | for (i = 0; i < 128; i++)
+// | for (j = 0; j < 128; j++)
+// | A(i,j);
+//
+// Prevector map:
+// [i,j] -> [it,j,ip] : it % 4 = 0 and it <= ip <= it + 3 and i = ip
+//
+// | After transformation:
+// |
+// | A[i,j] -> [it,j,ip] : it % 4 = 0 and it <= ip <= it + 3 and i = ip
+// |
+// | for (it = 0; it < 128; it+=4)
+// | for (j = 0; j < 128; j++)
+// | for (ip = max(0,it); ip < min(128, it + 3); ip++)
+// | A(ip,j);
+//
+// The goal of this transformation is to create a trivially vectorizable loop.
+// This means a parallel loop at the innermost level that has a constant number
+// of iterations corresponding to the target vector width.
+//
+// This transformation creates a loop at the innermost level. The loop has a
+// constant number of iterations, if the number of loop iterations at
+// DimToVectorize can be devided by VectorWidth. The default VectorWidth is
+// currently constant and not yet target specific. This function does not reason
+// about parallelism.
+static isl_map *getPrevectorMap(isl_ctx *ctx, int DimToVectorize,
+ int ScheduleDimensions,
+ int VectorWidth = 4) {
+ isl_space *Space;
+ isl_local_space *LocalSpace, *LocalSpaceRange;
+ isl_set *Modulo;
+ isl_map *TilingMap;
isl_constraint *c;
-
- isl_local_space *LocalSpace = isl_local_space_from_space(Space);
-
- for (int i = 0; i < vectorDimension; i++) {
+ isl_aff *Aff;
+ int PointDimension; /* ip */
+ int TileDimension; /* it */
+ isl_int VectorWidthMP;
+
+ assert (0 <= DimToVectorize && DimToVectorize < ScheduleDimensions);
+
+ Space = isl_space_alloc(ctx, 0, ScheduleDimensions, ScheduleDimensions + 1);
+ TilingMap = isl_map_universe(isl_space_copy(Space));
+ LocalSpace = isl_local_space_from_space(Space);
+ PointDimension = ScheduleDimensions;
+ TileDimension = DimToVectorize;
+
+ // Create an identity map for everything except DimToVectorize and map
+ // DimToVectorize to the point loop at the innermost dimension.
+ for (int i = 0; i < ScheduleDimensions; i++) {
c = isl_equality_alloc(isl_local_space_copy(LocalSpace));
isl_constraint_set_coefficient_si(c, isl_dim_in, i, -1);
- isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1);
- tilingMap = isl_basic_map_add_constraint(tilingMap, c);
- }
- for (int i = vectorDimension + 1; i < scheduleDimensions; i++) {
- c = isl_equality_alloc(isl_local_space_copy(LocalSpace));
- isl_constraint_set_coefficient_si(c, isl_dim_in, i, -1);
- isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1);
- tilingMap = isl_basic_map_add_constraint(tilingMap, c);
- }
+ if (i == DimToVectorize)
+ isl_constraint_set_coefficient_si(c, isl_dim_out, PointDimension, 1);
+ else
+ isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1);
- int stepDimension = scheduleDimensions;
- int auxilaryDimension = scheduleDimensions + 1;
+ TilingMap = isl_map_add_constraint(TilingMap, c);
+ }
- c = isl_equality_alloc(isl_local_space_copy(LocalSpace));
- isl_constraint_set_coefficient_si(c, isl_dim_out, vectorDimension, 1);
- isl_constraint_set_coefficient_si(c, isl_dim_out, auxilaryDimension,
- -vectorWidth);
- tilingMap = isl_basic_map_add_constraint(tilingMap, c);
-
- c = isl_equality_alloc(isl_local_space_copy(LocalSpace));
- isl_constraint_set_coefficient_si(c, isl_dim_in, vectorDimension, -1);
- isl_constraint_set_coefficient_si(c, isl_dim_out, stepDimension, 1);
- tilingMap = isl_basic_map_add_constraint(tilingMap, c);
+ // it % 'VectorWidth' = 0
+ LocalSpaceRange = isl_local_space_range(isl_local_space_copy(LocalSpace));
+ Aff = isl_aff_zero_on_domain(LocalSpaceRange);
+ Aff = isl_aff_set_constant_si(Aff, VectorWidth);
+ Aff = isl_aff_set_coefficient_si(Aff, isl_dim_in, TileDimension, 1);
+ isl_int_init(VectorWidthMP);
+ isl_int_set_si(VectorWidthMP, VectorWidth);
+ Aff = isl_aff_mod(Aff, VectorWidthMP);
+ isl_int_clear(VectorWidthMP);
+ Modulo = isl_pw_aff_zero_set(isl_pw_aff_from_aff(Aff));
+ TilingMap = isl_map_intersect_range(TilingMap, Modulo);
+ // it <= ip
c = isl_inequality_alloc(isl_local_space_copy(LocalSpace));
- isl_constraint_set_coefficient_si(c, isl_dim_out, vectorDimension, -1);
- isl_constraint_set_coefficient_si(c, isl_dim_out, stepDimension, 1);
- tilingMap = isl_basic_map_add_constraint(tilingMap, c);
+ isl_constraint_set_coefficient_si(c, isl_dim_out, TileDimension, -1);
+ isl_constraint_set_coefficient_si(c, isl_dim_out, PointDimension, 1);
+ TilingMap = isl_map_add_constraint(TilingMap, c);
+ // ip <= it + ('VectorWidth' - 1)
c = isl_inequality_alloc(LocalSpace);
- isl_constraint_set_coefficient_si(c, isl_dim_out, vectorDimension, 1);
- isl_constraint_set_coefficient_si(c, isl_dim_out, stepDimension, -1);
- isl_constraint_set_constant_si(c, vectorWidth- 1);
- tilingMap = isl_basic_map_add_constraint(tilingMap, c);
+ isl_constraint_set_coefficient_si(c, isl_dim_out, TileDimension, 1);
+ isl_constraint_set_coefficient_si(c, isl_dim_out, PointDimension, -1);
+ isl_constraint_set_constant_si(c, VectorWidth - 1);
+ TilingMap = isl_map_add_constraint(TilingMap, c);
- // Project out auxilary dimensions (introduced to ensure 'ii % tileSize = 0')
- //
- // 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.
- tilingMap = isl_basic_map_project_out(tilingMap, isl_dim_out,
- scheduleDimensions + 1, 1);
+ isl_map_dump(TilingMap);
- return isl_map_from_basic_map(tilingMap);
+ return TilingMap;
}
// getScheduleForBandList - Get the scheduling map for a list of bands.
@@ -328,7 +368,7 @@
isl_union_map *TileUMap;
TileMap = getPrevectorMap(ctx, ScheduleDimensions + i,
- ScheduleDimensions * 2, 0);
+ ScheduleDimensions * 2);
TileUMap = isl_union_map_from_map(TileMap);
TileUMap = isl_union_map_align_params(TileUMap,
isl_space_copy(Space));
More information about the llvm-commits
mailing list