18#include "llvm/Support/Debug.h"
19#define DEBUG_TYPE "polly-flatten-algo"
29bool isDimBoundedByConstant(
isl::set Set,
unsigned dim) {
43bool isDimBoundedByParameter(
isl::set Set,
unsigned dim) {
54 return FixedVal.
is_null() || FixedVal.is_nan();
58bool isVariableDim(
const isl::map &Map) {
60 if (isVariableDim(BMap))
69 if (isVariableDim(Map))
84 auto Subtracted = PwAff.
sub(ValAff);
103 auto Multiplied = PwAff.
mul(ValAff);
125 Result = Result.
unite(Outprojected);
138 SingleUMap = SingleUMap.
unite(SingleMap);
143 return FirstMAff.at(0);
166 auto IslCtx = Schedule.
ctx();
174 if (!isDimBoundedByConstant(ScatterSet, 0)) {
175 POLLY_DEBUG(dbgs() <<
"Abort; dimension is not of fixed size\n");
179 auto AllDomains = Schedule.
domain();
185 while (!ScatterSet.is_empty()) {
186 POLLY_DEBUG(dbgs() <<
"Next counter:\n " << Counter <<
"\n");
187 POLLY_DEBUG(dbgs() <<
"Remaining scatter set:\n " << ScatterSet <<
"\n");
188 auto ThisSet = ScatterSet.project_out(
isl::dim::set, 1, Dims - 1);
189 auto ThisFirst = ThisSet.lexmin();
190 auto ScatterFirst = ThisFirst.add_dims(
isl::dim::set, Dims - 1);
193 SubSchedule = scheduleProjectOut(SubSchedule, 0, 1);
198 auto FirstSubSchedule = scheduleProjectOut(SubSchedule, 1, SubDims - 1);
199 auto FirstScheduleAff = scheduleExtractDimAff(FirstSubSchedule, 0);
200 auto RemainingSubSchedule = scheduleProjectOut(SubSchedule, 0, 1);
202 auto FirstSubScatter =
isl::set(FirstSubSchedule.range());
203 POLLY_DEBUG(dbgs() <<
"Next step in sequence is:\n " << FirstSubScatter
206 if (!isDimBoundedByParameter(FirstSubScatter, 0)) {
207 POLLY_DEBUG(dbgs() <<
"Abort; sequence step is not bounded\n");
218 auto PartMin = FirstSubScatterMap.dim_min(0);
219 auto PartMax = FirstSubScatterMap.dim_max(0);
222 auto PartLen = PartMax.add(PartMin.neg()).add(One);
225 auto FirstScheduleAffNormalized = FirstScheduleAff.
sub(AllPartMin);
227 auto FirstScheduleAffWithOffset =
228 FirstScheduleAffNormalized.
add(AllCounter);
230 auto ScheduleWithOffset =
234 NewSchedule = NewSchedule.
unite(ScheduleWithOffset);
236 ScatterSet = ScatterSet.
subtract(ScatterFirst);
237 Counter = Counter.add(PartLen);
240 POLLY_DEBUG(dbgs() <<
"Sequence-flatten result is:\n " << NewSchedule
258 auto Remaining = scheduleProjectOut(Schedule, 0, 1);
264 auto SubExtent =
isl::set(SubSchedule.range());
267 SubExtent = SubExtent.project_out(
isl::dim::set, 1, SubDims - 1);
269 if (!isDimBoundedByConstant(SubExtent, 0)) {
270 POLLY_DEBUG(dbgs() <<
"Abort; dimension not bounded by constant\n");
274 auto Min = SubExtent.dim_min(0);
275 POLLY_DEBUG(dbgs() <<
"Min bound:\n " << Min <<
"\n");
277 auto Max = SubExtent.dim_max(0);
278 POLLY_DEBUG(dbgs() <<
"Max bound:\n " << Max <<
"\n");
281 if (MinVal.is_null() || MaxVal.is_null() || MinVal.is_nan() ||
283 POLLY_DEBUG(dbgs() <<
"Abort; dimension bounds could not be determined\n");
287 auto FirstSubScheduleAff = scheduleExtractDimAff(SubSchedule, 0);
288 auto RemainingSubSchedule = scheduleProjectOut(std::move(SubSchedule), 0, 1);
290 auto LenVal = MaxVal.sub(MinVal).add(1);
291 auto FirstSubScheduleNormalized =
subtract(FirstSubScheduleAff, MinVal);
295 auto FirstAff = scheduleExtractDimAff(Schedule, 0);
296 auto Offset = multiply(FirstAff, LenVal);
300 auto Result = IndexMap.flat_range_product(RemainingSubSchedule);
301 POLLY_DEBUG(dbgs() <<
"Loop-flatten result is:\n " << Result <<
"\n");
308 POLLY_DEBUG(dbgs() <<
"Recursive schedule to process:\n " << Schedule
322 if (!isVariableDim(Schedule)) {
323 POLLY_DEBUG(dbgs() <<
"Fixed dimension; try sequence flattening\n");
324 auto NewScheduleSequence = tryFlattenSequence(Schedule);
325 if (!NewScheduleSequence.is_null())
326 return NewScheduleSequence;
331 auto NewScheduleLoop = tryFlattenLoop(Schedule);
332 if (!NewScheduleLoop.is_null())
333 return NewScheduleLoop;
336 POLLY_DEBUG(dbgs() <<
"Try sequence flattening again\n");
337 auto NewScheduleSequence = tryFlattenSequence(Schedule);
338 if (!NewScheduleSequence.is_null())
339 return NewScheduleSequence;
isl::val plain_get_val_if_fixed(isl::dim type, unsigned int pos) const
isl::basic_map_list get_basic_map_list() const
class size range_tuple_dim() const
isl::map unite(isl::map map2) const
isl::map project_out(isl::dim type, unsigned int first, unsigned int n) const
static isl::map from_range(isl::set set)
isl::multi_pw_aff union_add(isl::multi_pw_aff mpa2) const
isl::multi_pw_aff sub(const isl::multi_pw_aff &multi2) const
isl::multi_pw_aff union_add(const isl::multi_pw_aff &mpa2) const
isl::space get_space() const
isl::pw_aff mul(isl::pw_aff pwaff2) const
isl::set project_out(isl::dim type, unsigned int first, unsigned int n) const
static isl::set universe(isl::space space)
boolean is_bounded() const
class size tuple_dim() const
class size dim(isl::dim type) const
isl::space params() const
isl::space domain() const
isl::union_set range() const
isl::union_map unite(isl::union_map umap2) const
isl::union_set domain() const
isl::map_list get_map_list() const
isl::union_map flat_range_product(isl::union_map umap2) const
isl::space get_space() const
isl::union_map intersect_range(isl::space space) const
static isl::union_map empty(isl::ctx ctx)
isl::union_map subtract(isl::union_map umap2) const
static isl::union_map from(isl::multi_union_pw_aff mupa)
isl::space get_space() const
isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const
stat foreach_pw_aff(const std::function< stat(isl::pw_aff)> &fn) const
isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const
static isl::union_pw_aff empty(isl::space space)
isl::union_pw_aff pullback(isl::union_pw_multi_aff upma) const
isl::union_pw_multi_aff add(isl::union_pw_multi_aff upma2) const
static isl::val one(isl::ctx ctx)
static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type)
static void subtract(__isl_keep isl_mat *M, __isl_keep isl_mat **U, __isl_keep isl_mat **Q, unsigned row, unsigned i, unsigned j, isl_int m)
This file contains the declaration of the PolyhedralInfo class, which will provide an interface to ex...
unsigned getNumScatterDims(const isl::union_map &Schedule)
Determine how many dimensions the scatter space of Schedule has.
isl::val getConstant(isl::pw_aff PwAff, bool Max, bool Min)
If PwAff maps to a constant, return said constant.
isl::union_map flattenSchedule(isl::union_map Schedule)
Recursively flatten a schedule.