From c6699b7fe856ebba10bfcbdfe5f022e260364e2a Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Thu, 30 Jun 2011 20:29:13 +0000 Subject: [PATCH] ScheduleOpt: Add first version of prevectorization We just strip-mine the innermost dimension by the vector width. This does not take into account if this dimension is parallel nor if it is constant. llvm-svn: 134186 --- polly/lib/ScheduleOptimizer.cpp | 83 +++++++++++++++++++++++++++++++++ polly/utils/pollycc | 4 +- 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/polly/lib/ScheduleOptimizer.cpp b/polly/lib/ScheduleOptimizer.cpp index 0fb4565c1409..b8e6c43afa56 100644 --- a/polly/lib/ScheduleOptimizer.cpp +++ b/polly/lib/ScheduleOptimizer.cpp @@ -32,10 +32,17 @@ #define DEBUG_TYPE "polly-optimize-isl" #include "llvm/Support/Debug.h" +#include "llvm/Support/CommandLine.h" using namespace llvm; using namespace polly; +static cl::opt +Prevector("enable-schedule-prevector", + cl::desc("Enable the prevectorization in the scheduler"), cl::Hidden, + cl::value_desc("Prevectorization enabled"), + cl::init(false)); + namespace { class ScheduleOptimizer : public ScopPass { @@ -203,6 +210,68 @@ isl_union_map *getTiledPartialSchedule(isl_band *band) { return partialSchedule; } +static isl_map *getPrevectorMap(isl_ctx *ctx, int vectorDimension, + int scheduleDimensions, + int parameterDimensions, + int vectorWidth = 4) { + assert (0 <= vectorDimension < scheduleDimensions); + + isl_dim *dim = isl_dim_alloc(ctx, parameterDimensions, scheduleDimensions, + scheduleDimensions + 2); + isl_basic_map *tilingMap = isl_basic_map_universe(isl_dim_copy(dim)); + + isl_constraint *c; + + for (int i = 0; i < vectorDimension; i++) { + 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, i, 1); + tilingMap = isl_basic_map_add_constraint(tilingMap, c); + } + + for (int i = vectorDimension + 1; i < scheduleDimensions; i++) { + 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, i, 1); + tilingMap = isl_basic_map_add_constraint(tilingMap, c); + } + + int stepDimension = scheduleDimensions; + int auxilaryDimension = scheduleDimensions + 1; + + c = isl_equality_alloc(isl_dim_copy(dim)); + 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_dim_copy(dim)); + 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); + + c = isl_inequality_alloc(isl_dim_copy(dim)); + 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); + + c = isl_inequality_alloc(isl_dim_copy(dim)); + 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); + + // 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); + + return isl_map_from_basic_map(tilingMap); +} + // tileBandList - Tile all bands contained in a band forest. // // Recursively walk the band forest and tile all bands in the forest. Return @@ -223,6 +292,20 @@ static isl_union_map *tileBandList(isl_band_list *blist) { isl_union_map *suffixSchedule = tileBandList(children); partialSchedule = isl_union_map_flat_range_product(partialSchedule, suffixSchedule); + } else if (Prevector) { + isl_map *tileMap; + isl_union_map *tileUnionMap; + isl_ctx *ctx; + int scheduleDimensions, parameterDimensions; + + ctx = isl_union_map_get_ctx(partialSchedule); + scheduleDimensions = isl_band_n_member(band); + tileMap = getPrevectorMap(ctx, scheduleDimensions * 2 - 1, + scheduleDimensions * 2, + parameterDimensions); + tileUnionMap = isl_union_map_from_map(tileMap); + partialSchedule = isl_union_map_apply_range(partialSchedule, + tileUnionMap); } if (finalSchedule) diff --git a/polly/utils/pollycc b/polly/utils/pollycc index e9999ae62145..7c3bb2b7ff38 100755 --- a/polly/utils/pollycc +++ b/polly/utils/pollycc @@ -115,7 +115,9 @@ def createAssemblyFile(tmpDir, file, number, args, polly): if args.fvector: commandLine.append('-enable-polly-vector') - commandLine.append('-enable-pluto-prevector') + commandLine.append('-enable-schedule-prevector') + if (args.ftile or args.fpluto): + commandLine.append('-enable-pluto-prevector') if args.pollyexport: commandLine.append('-polly-export-jscop')