Polly 19.0.0git
ISLTools.h
Go to the documentation of this file.
1//===------ ISLTools.h ------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Tools, utilities, helpers and extensions useful in conjunction with the
10// Integer Set Library (isl).
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef POLLY_ISLTOOLS_H
15#define POLLY_ISLTOOLS_H
16
17#include "llvm/ADT/Sequence.h"
18#include "llvm/ADT/iterator.h"
20#include <algorithm>
21#include <cassert>
22
23/// In debug builds assert that the @p Size is valid, in non-debug builds
24/// disable the mandatory state checking but do not enforce the error checking.
25inline void islAssert(const isl::size &Size) {
26#ifdef NDEBUG
27 // Calling is_error() marks that the error status has been checked which
28 // disables the error-status-not-checked errors that would otherwise occur
29 // when using the value.
30 (void)Size.is_error();
31#else
32 // Assert on error in debug builds.
33 assert(!Size.is_error());
34#endif
35}
36
37/// Check that @p Size is valid (only on debug builds) and cast it to unsigned.
38/// Cast the @p Size to unsigned. If the @p Size is not valid (Size.is_error()
39/// == true) then an assert and an abort are triggered.
40inline unsigned unsignedFromIslSize(const isl::size &Size) {
41 islAssert(Size);
42 return static_cast<unsigned>(Size);
43}
44
45namespace isl {
46inline namespace noexceptions {
47
48template <typename ListT>
49using list_element_type = decltype(std::declval<ListT>().get_at(0));
50
51template <typename ListT>
53 : public llvm::iterator_facade_base<isl_iterator<ListT>,
54 std::forward_iterator_tag,
55 list_element_type<ListT>> {
56public:
58
59 explicit isl_iterator(const ListT &List)
60 : List(&List), Position(std::max(List.size().release(), 0)) {}
61 isl_iterator(const ListT &List, int Position)
62 : List(&List), Position(Position) {}
63
64 bool operator==(const isl_iterator &O) const {
65 return List == O.List && Position == O.Position;
66 }
67
69 ++Position;
70 return *this;
71 }
72
74 isl_iterator Copy{*this};
75 ++Position;
76 return Copy;
77 }
78
79 ElementT operator*() const { return List->get_at(this->Position); }
80
81protected:
82 const ListT *List;
83 int Position = 0;
84};
85
86template <typename T> isl_iterator<T> begin(const T &t) {
87 return isl_iterator<T>(t, 0);
88}
89template <typename T> isl_iterator<T> end(const T &t) {
90 return isl_iterator<T>(t);
91}
92
93} // namespace noexceptions
94} // namespace isl
95
96namespace polly {
97
98/// Return the range elements that are lexicographically smaller.
99///
100/// @param Map { Space[] -> Scatter[] }
101/// @param Strict True for strictly lexicographically smaller elements (exclude
102/// same timepoints from the result).
103///
104/// @return { Space[] -> Scatter[] }
105/// A map to all timepoints that happen before the timepoints the input
106/// mapped to.
107isl::map beforeScatter(isl::map Map, bool Strict);
108
109/// Piecewise beforeScatter(isl::map,bool).
111
112/// Return the range elements that are lexicographically larger.
113///
114/// @param Map { Space[] -> Scatter[] }
115/// @param Strict True for strictly lexicographically larger elements (exclude
116/// same timepoints from the result).
117///
118/// @return { Space[] -> Scatter[] }
119/// A map to all timepoints that happen after the timepoints the input
120/// map originally mapped to.
121isl::map afterScatter(isl::map Map, bool Strict);
122
123/// Piecewise afterScatter(isl::map,bool).
124isl::union_map afterScatter(const isl::union_map &UMap, bool Strict);
125
126/// Construct a range of timepoints between two timepoints.
127///
128/// Example:
129/// From := { A[] -> [0]; B[] -> [0] }
130/// To := { B[] -> [10]; C[] -> [20] }
131///
132/// Result:
133/// { B[] -> [i] : 0 < i < 10 }
134///
135/// Note that A[] and C[] are not in the result because they do not have a start
136/// or end timepoint. If a start (or end) timepoint is not unique, the first
137/// (respectively last) is chosen.
138///
139/// @param From { Space[] -> Scatter[] }
140/// Map to start timepoints.
141/// @param To { Space[] -> Scatter[] }
142/// Map to end timepoints.
143/// @param InclFrom Whether to include the start timepoints in the result. In
144/// the example, this would add { B[] -> [0] }
145/// @param InclTo Whether to include the end timepoints in the result. In this
146/// example, this would add { B[] -> [10] }
147///
148/// @return { Space[] -> Scatter[] }
149/// A map for each domain element of timepoints between two extreme
150/// points, or nullptr if @p From or @p To is nullptr, or the isl max
151/// operations is exceeded.
152isl::map betweenScatter(isl::map From, isl::map To, bool InclFrom, bool InclTo);
153
154/// Piecewise betweenScatter(isl::map,isl::map,bool,bool).
156 bool InclFrom, bool InclTo);
157
158/// If by construction a union map is known to contain only a single map, return
159/// it.
160///
161/// This function combines isl_map_from_union_map() and
162/// isl_union_map_extract_map(). isl_map_from_union_map() fails if the map is
163/// empty because it does not know which space it would be in.
164/// isl_union_map_extract_map() on the other hand does not check whether there
165/// is (at most) one isl_map in the union, i.e. how it has been constructed is
166/// probably wrong.
167isl::map singleton(isl::union_map UMap, isl::space ExpectedSpace);
168
169/// If by construction an isl_union_set is known to contain only a single
170/// isl_set, return it.
171///
172/// This function combines isl_set_from_union_set() and
173/// isl_union_set_extract_set(). isl_map_from_union_set() fails if the set is
174/// empty because it does not know which space it would be in.
175/// isl_union_set_extract_set() on the other hand does not check whether there
176/// is (at most) one isl_set in the union, i.e. how it has been constructed is
177/// probably wrong.
178isl::set singleton(isl::union_set USet, isl::space ExpectedSpace);
179
180/// Determine how many dimensions the scatter space of @p Schedule has.
181///
182/// The schedule must not be empty and have equal number of dimensions of any
183/// subspace it contains.
184///
185/// The implementation currently returns the maximum number of dimensions it
186/// encounters, if different, and 0 if none is encountered. However, most other
187/// code will most likely fail if one of these happen.
188unsigned getNumScatterDims(const isl::union_map &Schedule);
189
190/// Return the scatter space of a @p Schedule.
191///
192/// This is basically the range space of the schedule map, but harder to
193/// determine because it is an isl_union_map.
195
196/// Construct an identity map for the given domain values.
197///
198/// @param USet { Space[] }
199/// The returned map's domain and range.
200/// @param RestrictDomain If true, the returned map only maps elements contained
201/// in @p Set and no other. If false, it returns an
202/// overapproximation with the identity maps of any space
203/// in @p Set, not just the elements in it.
204///
205/// @return { Space[] -> Space[] }
206/// A map that maps each value of @p Set to itself.
207isl::map makeIdentityMap(const isl::set &Set, bool RestrictDomain);
208
209/// Construct an identity map for the given domain values.
210///
211/// There is no type resembling isl_union_space, hence we have to pass an
212/// isl_union_set as the map's domain and range space.
213///
214/// @param USet { Space[] }
215/// The returned map's domain and range.
216/// @param RestrictDomain If true, the returned map only maps elements contained
217/// in @p USet and no other. If false, it returns an
218/// overapproximation with the identity maps of any space
219/// in @p USet, not just the elements in it.
220///
221/// @return { Space[] -> Space[] }
222/// A map that maps each value of @p USet to itself.
223isl::union_map makeIdentityMap(const isl::union_set &USet, bool RestrictDomain);
224
225/// Reverse the nested map tuple in @p Map's domain.
226///
227/// @param Map { [Space1[] -> Space2[]] -> Space3[] }
228///
229/// @return { [Space2[] -> Space1[]] -> Space3[] }
231
232/// Piecewise reverseDomain(isl::map).
234
235/// Add a constant to one dimension of a set.
236///
237/// @param Map The set to shift a dimension in.
238/// @param Pos The dimension to shift. If negative, the dimensions are
239/// counted from the end instead from the beginning. E.g. -1 is
240/// the last dimension in the tuple.
241/// @param Amount The offset to add to the specified dimension.
242///
243/// @return The modified set.
244isl::set shiftDim(isl::set Set, int Pos, int Amount);
245
246/// Piecewise shiftDim(isl::set,int,int).
247isl::union_set shiftDim(isl::union_set USet, int Pos, int Amount);
248
249/// Add a constant to one dimension of a map.
250///
251/// @param Map The map to shift a dimension in.
252/// @param Type A tuple of @p Map which contains the dimension to shift.
253/// @param Pos The dimension to shift. If negative, the dimensions are
254/// counted from the end instead from the beginning. Eg. -1 is the last
255/// dimension in the tuple.
256/// @param Amount The offset to add to the specified dimension.
257///
258/// @return The modified map.
259isl::map shiftDim(isl::map Map, isl::dim Dim, int Pos, int Amount);
260
261/// Add a constant to one dimension of a each map in a union map.
262///
263/// @param UMap The maps to shift a dimension in.
264/// @param Type The tuple which contains the dimension to shift.
265/// @param Pos The dimension to shift. If negative, the dimensions are
266/// counted from the ends of each map of union instead from their
267/// beginning. E.g. -1 is the last dimension of any map.
268/// @param Amount The offset to add to the specified dimension.
269///
270/// @return The union of all modified maps.
271isl::union_map shiftDim(isl::union_map UMap, isl::dim Dim, int Pos, int Amount);
272
273/// Simplify a set inplace.
274void simplify(isl::set &Set);
275
276/// Simplify a union set inplace.
277void simplify(isl::union_set &USet);
278
279/// Simplify a map inplace.
280void simplify(isl::map &Map);
281
282/// Simplify a union map inplace.
283void simplify(isl::union_map &UMap);
284
285/// Compute the reaching definition statement or the next overwrite for each
286/// definition of an array element.
287///
288/// The reaching definition of an array element at a specific timepoint is the
289/// statement instance that has written the current element's content.
290/// Alternatively, this function determines for each timepoint and element which
291/// write is going to overwrite an element at a future timepoint. This can be
292/// seen as "reaching definition in reverse" where definitions are found in the
293/// past.
294///
295/// For example:
296///
297/// Schedule := { Write[] -> [0]; Overwrite[] -> [10] }
298/// Defs := { Write[] -> A[5]; Overwrite[] -> A[5] }
299///
300/// If index 5 of array A is written at timepoint 0 and 10, the resulting
301/// reaching definitions are:
302///
303/// { [A[5] -> [i]] -> Write[] : 0 < i < 10;
304/// [A[5] -> [i]] -> Overwrite[] : 10 < i }
305///
306/// Between timepoint 0 (Write[]) and timepoint 10 (Overwrite[]), the
307/// content of A[5] is written by statement instance Write[] and after
308/// timepoint 10 by Overwrite[]. Values not defined in the map have no known
309/// definition. This includes the statement instance timepoints themselves,
310/// because reads at those timepoints could either read the old or the new
311/// value, defined only by the statement itself. But this can be changed by @p
312/// InclPrevDef and @p InclNextDef. InclPrevDef=false and InclNextDef=true
313/// returns a zone. Unless @p InclPrevDef and @p InclNextDef are both true,
314/// there is only one unique definition per element and timepoint.
315///
316/// @param Schedule { DomainWrite[] -> Scatter[] }
317/// Schedule of (at least) all array writes. Instances not in
318/// @p Writes are ignored.
319/// @param Writes { DomainWrite[] -> Element[] }
320/// Elements written to by the statement instances.
321/// @param Reverse If true, look for definitions in the future. That is,
322/// find the write that is overwrites the current value.
323/// @param InclPrevDef Include the definition's timepoint to the set of
324/// well-defined elements (any load at that timepoint happen
325/// at the writes). In the example, enabling this option adds
326/// {[A[5] -> [0]] -> Write[]; [A[5] -> [10]] -> Overwrite[]}
327/// to the result.
328/// @param InclNextDef Whether to assume that at the timepoint where an element
329/// is overwritten, it still contains the old value (any load
330/// at that timepoint would happen before the overwrite). In
331/// this example, enabling this adds
332/// { [A[] -> [10]] -> Write[] } to the result.
333///
334/// @return { [Element[] -> Scatter[]] -> DomainWrite[] }
335/// The reaching definitions or future overwrite as described above, or
336/// nullptr if either @p Schedule or @p Writes is nullptr, or the isl
337/// max operations count has exceeded.
339 isl::union_map Writes, bool Reverse,
340 bool InclPrevDef, bool InclNextDef);
341
342/// Compute the timepoints where the contents of an array element are not used.
343///
344/// An element is unused at a timepoint when the element is overwritten in
345/// the future, but it is not read in between. Another way to express this: the
346/// time from when the element is written, to the most recent read before it, or
347/// infinitely into the past if there is no read before. Such unused elements
348/// can be overwritten by any value without changing the scop's semantics. An
349/// example:
350///
351/// Schedule := { Read[] -> [0]; Write[] -> [10]; Def[] -> [20] }
352/// Writes := { Write[] -> A[5]; Def[] -> A[6] }
353/// Reads := { Read[] -> A[5] }
354///
355/// The result is:
356///
357/// { A[5] -> [i] : 0 < i < 10;
358/// A[6] -> [i] : i < 20 }
359///
360/// That is, A[5] is unused between timepoint 0 (the read) and timepoint 10 (the
361/// write). A[6] is unused before timepoint 20, but might be used after the
362/// scop's execution (A[5] and any other A[i] as well). Use InclLastRead=false
363/// and InclWrite=true to interpret the result as zone.
364///
365/// @param Schedule { Domain[] -> Scatter[] }
366/// The schedule of (at least) all statement instances
367/// occurring in @p Writes or @p Reads. All other
368/// instances are ignored.
369/// @param Writes { DomainWrite[] -> Element[] }
370/// Elements written to by the statement instances.
371/// @param Reads { DomainRead[] -> Element[] }
372/// Elements read from by the statement instances.
373/// @param ReadEltInSameInst Whether a load reads the value from a write
374/// that is scheduled at the same timepoint (Writes
375/// happen before reads). Otherwise, loads use the
376/// value of an element that it had before the
377/// timepoint (Reads before writes). For example:
378/// { Read[] -> [0]; Write[] -> [0] }
379/// With ReadEltInSameInst=false it is assumed that the
380/// read happens before the write, such that the
381/// element is never unused, or just at timepoint 0,
382/// depending on InclLastRead/InclWrite.
383/// With ReadEltInSameInst=false it assumes that the
384/// value just written is used. Anything before
385/// timepoint 0 is considered unused.
386/// @param InclLastRead Whether a timepoint where an element is last read
387/// counts as unused (the read happens at the beginning
388/// of its timepoint, and nothing (else) can use it
389/// during the timepoint). In the example, this option
390/// adds { A[5] -> [0] } to the result.
391/// @param InclWrite Whether the timepoint where an element is written
392/// itself counts as unused (the write happens at the
393/// end of its timepoint; no (other) operations uses
394/// the element during the timepoint). In this example,
395/// this adds
396/// { A[5] -> [10]; A[6] -> [20] } to the result.
397///
398/// @return { Element[] -> Scatter[] }
399/// The unused timepoints as defined above, or nullptr if either @p
400/// Schedule, @p Writes are @p Reads is nullptr, or the ISL max
401/// operations count is exceeded.
403 isl::union_map Writes, isl::union_map Reads,
404 bool ReadEltInSameInst, bool InclLastRead,
405 bool InclWrite);
406
407/// Convert a zone (range between timepoints) to timepoints.
408///
409/// A zone represents the time between (integer) timepoints, but not the
410/// timepoints themselves. This function can be used to determine whether a
411/// timepoint lies within a zone.
412///
413/// For instance, the range (1,3), representing the time between 1 and 3, is
414/// represented by the zone
415///
416/// { [i] : 1 < i <= 3 }
417///
418/// The set of timepoints that lie completely within this range is
419///
420/// { [i] : 1 < i < 3 }
421///
422/// A typical use-case is the range in which a value written by a store is
423/// available until it is overwritten by another value. If the write is at
424/// timepoint 1 and its value is overwritten by another value at timepoint 3,
425/// the value is available between those timepoints: timepoint 2 in this
426/// example.
427///
428///
429/// When InclStart is true, the range is interpreted left-inclusive, i.e. adds
430/// the timepoint 1 to the result:
431///
432/// { [i] : 1 <= i < 3 }
433///
434/// In the use-case mentioned above that means that the value written at
435/// timepoint 1 is already available in timepoint 1 (write takes place before
436/// any read of it even if executed at the same timepoint)
437///
438/// When InclEnd is true, the range is interpreted right-inclusive, i.e. adds
439/// the timepoint 3 to the result:
440///
441/// { [i] : 1 < i <= 3 }
442///
443/// In the use-case mentioned above that means that although the value is
444/// overwritten in timepoint 3, the old value is still available at timepoint 3
445/// (write takes place after any read even if executed at the same timepoint)
446///
447/// @param Zone { Zone[] }
448/// @param InclStart Include timepoints adjacent to the beginning of a zone.
449/// @param InclEnd Include timepoints adjacent to the ending of a zone.
450///
451/// @return { Scatter[] }
453 bool InclEnd);
454
455/// Like convertZoneToTimepoints(isl::union_set,InclStart,InclEnd), but convert
456/// either the domain or the range of a map.
458 bool InclStart, bool InclEnd);
459
460/// Overload of convertZoneToTimepoints(isl::map,InclStart,InclEnd) to process
461/// only a single map.
462isl::map convertZoneToTimepoints(isl::map Zone, isl::dim Dim, bool InclStart,
463 bool InclEnd);
464
465/// Distribute the domain to the tuples of a wrapped range map.
466///
467/// @param Map { Domain[] -> [Range1[] -> Range2[]] }
468///
469/// @return { [Domain[] -> Range1[]] -> [Domain[] -> Range2[]] }
471
472/// Apply distributeDomain(isl::map) to each map in the union.
474
475/// Prepend a space to the tuples of a map.
476///
477/// @param UMap { Domain[] -> Range[] }
478/// @param Factor { Factor[] }
479///
480/// @return { [Factor[] -> Domain[]] -> [Factor[] -> Range[]] }
482
483/// Apply a map to the 'middle' of another relation.
484///
485/// @param UMap { [DomainDomain[] -> DomainRange[]] -> Range[] }
486/// @param Func { DomainRange[] -> NewDomainRange[] }
487///
488/// @return { [DomainDomain[] -> NewDomainRange[]] -> Range[] }
490
491/// Intersect the range of @p Map with @p Range.
492///
493/// Since @p Map is an isl::map, the result will be a single space, even though
494/// @p Range is an isl::union_set. This is the only difference to
495/// isl::map::intersect_range and isl::union_map::interset_range.
496///
497/// @param Map { Domain[] -> Range[] }
498/// @param Range { Range[] }
499///
500/// @return { Domain[] -> Range[] }
502
503/// Subtract the parameter space @p Params from @p Map.
504/// This is akin to isl::map::intersect_params.
505///
506/// Example:
507/// subtractParams(
508/// { [i] -> [i] },
509/// [x] -> { : x < 0 }
510/// ) = [x] -> { [i] -> [i] : x >= 0 }
511///
512/// @param Map Remove the conditions of @p Params from this map.
513/// @param Params Parameter set to subtract.
514///
515/// @param The map with the parameter conditions removed.
517
518/// Subtract the parameter space @p Params from @p Set.
520
521/// If @p PwAff maps to a constant, return said constant. If @p Max/@p Min, it
522/// can also be a piecewise constant and it would return the minimum/maximum
523/// value. Otherwise, return NaN.
524isl::val getConstant(isl::pw_aff PwAff, bool Max, bool Min);
525
526/// If the relation @p PwAff lies on a hyperplane where the given
527/// dimension @p Pos with the type @p Dim has a fixed value, then
528/// return that value. Otherwise return NaN.
529isl::val getConstant(isl::map Map, isl::dim Dim, int Pos);
530
531/// Check that @p End is valid and return an iterator from @p Begin to @p End
532///
533/// Use case example:
534/// for (unsigned i : rangeIslSize(0, Map.domain_tuple_dim()))
535/// // do stuff
536llvm::iota_range<unsigned> rangeIslSize(unsigned Begin, isl::size End);
537
538/// Dump a description of the argument to llvm::errs().
539///
540/// In contrast to isl's dump function, there are a few differences:
541/// - Each polyhedron (pieces) is written on its own line.
542/// - Spaces are sorted by structure. E.g. maps with same domain space are
543/// grouped. Isl sorts them according to the space's hash function.
544/// - Pieces of the same space are sorted using their lower bound.
545/// - A more compact to_str representation is used instead of Isl's dump
546/// functions that try to show the internal representation.
547///
548/// The goal is to get a better understandable representation that is also
549/// useful to compare two sets. As all dump() functions, its intended use is to
550/// be called in a debugger only.
551///
552/// isl_map_dump example:
553/// [p_0, p_1, p_2] -> { Stmt0[i0] -> [o0, o1] : (o0 = i0 and o1 = 0 and i0 > 0
554/// and i0 <= 5 - p_2) or (i0 = 0 and o0 = 0 and o1 = 0); Stmt3[i0] -> [o0, o1]
555/// : (o0 = i0 and o1 = 3 and i0 > 0 and i0 <= 5 - p_2) or (i0 = 0 and o0 = 0
556/// and o1 = 3); Stmt2[i0] -> [o0, o1] : (o0 = i0 and o1 = 1 and i0 >= 3 + p_0 -
557/// p_1 and i0 > 0 and i0 <= 5 - p_2) or (o0 = i0 and o1 = 1 and i0 > 0 and i0
558/// <= 5 - p_2 and i0 < p_0 - p_1) or (i0 = 0 and o0 = 0 and o1 = 1 and p_1 >= 3
559/// + p_0) or (i0 = 0 and o0 = 0 and o1 = 1 and p_1 < p_0) or (p_0 = 0 and i0 =
560/// 2 - p_1 and o0 = 2 - p_1 and o1 = 1 and p_2 <= 3 + p_1 and p_1 <= 1) or (p_1
561/// = 1 + p_0 and i0 = 0 and o0 = 0 and o1 = 1) or (p_0 = 0 and p_1 = 2 and i0 =
562/// 0 and o0 = 0 and o1 = 1) or (p_0 = -1 and p_1 = -1 and i0 = 0 and o0 = 0 and
563/// o1 = 1); Stmt1[i0] -> [o0, o1] : (p_0 = -1 and i0 = 1 - p_1 and o0 = 1 - p_1
564/// and o1 = 2 and p_2 <= 4 + p_1 and p_1 <= 0) or (p_0 = 0 and i0 = -p_1 and o0
565/// = -p_1 and o1 = 2 and p_2 <= 5 + p_1 and p_1 < 0) or (p_0 = -1 and p_1 = 1
566/// and i0 = 0 and o0 = 0 and o1 = 2) or (p_0 = 0 and p_1 = 0 and i0 = 0 and o0
567/// = 0 and o1 = 2) }
568///
569/// dumpPw example (same set):
570/// [p_0, p_1, p_2] -> {
571/// Stmt0[0] -> [0, 0];
572/// Stmt0[i0] -> [i0, 0] : 0 < i0 <= 5 - p_2;
573/// Stmt1[0] -> [0, 2] : p_1 = 1 and p_0 = -1;
574/// Stmt1[0] -> [0, 2] : p_1 = 0 and p_0 = 0;
575/// Stmt1[1 - p_1] -> [1 - p_1, 2] : p_0 = -1 and p_1 <= 0 and p_2 <= 4 + p_1;
576/// Stmt1[-p_1] -> [-p_1, 2] : p_0 = 0 and p_1 < 0 and p_2 <= 5 + p_1;
577/// Stmt2[0] -> [0, 1] : p_1 >= 3 + p_0;
578/// Stmt2[0] -> [0, 1] : p_1 < p_0;
579/// Stmt2[0] -> [0, 1] : p_1 = 1 + p_0;
580/// Stmt2[0] -> [0, 1] : p_1 = 2 and p_0 = 0;
581/// Stmt2[0] -> [0, 1] : p_1 = -1 and p_0 = -1;
582/// Stmt2[i0] -> [i0, 1] : i0 >= 3 + p_0 - p_1 and 0 < i0 <= 5 - p_2;
583/// Stmt2[i0] -> [i0, 1] : 0 < i0 <= 5 - p_2 and i0 < p_0 - p_1;
584/// Stmt2[2 - p_1] -> [2 - p_1, 1] : p_0 = 0 and p_1 <= 1 and p_2 <= 3 + p_1;
585/// Stmt3[0] -> [0, 3];
586/// Stmt3[i0] -> [i0, 3] : 0 < i0 <= 5 - p_2
587/// }
588/// @{
589void dumpPw(const isl::set &Set);
590void dumpPw(const isl::map &Map);
591void dumpPw(const isl::union_set &USet);
592void dumpPw(const isl::union_map &UMap);
593void dumpPw(__isl_keep isl_set *Set);
594void dumpPw(__isl_keep isl_map *Map);
597/// @}
598
599/// Dump all points of the argument to llvm::errs().
600///
601/// Before being printed by dumpPw(), the argument's pieces are expanded to
602/// contain only single points. If a dimension is unbounded, it keeps its
603/// representation.
604///
605/// This is useful for debugging reduced cases where parameters are set to
606/// constants to keep the example simple. Such sets can still contain
607/// existential dimensions which makes the polyhedral hard to compare.
608///
609/// Example:
610/// { [MemRef_A[i0] -> [i1]] : (exists (e0 = floor((1 + i1)/3): i0 = 1 and 3e0
611/// <= i1 and 3e0 >= -1 + i1 and i1 >= 15 and i1 <= 25)) or (exists (e0 =
612/// floor((i1)/3): i0 = 0 and 3e0 < i1 and 3e0 >= -2 + i1 and i1 > 0 and i1 <=
613/// 11)) }
614///
615/// dumpExpanded:
616/// {
617/// [MemRef_A[0] ->[1]];
618/// [MemRef_A[0] ->[2]];
619/// [MemRef_A[0] ->[4]];
620/// [MemRef_A[0] ->[5]];
621/// [MemRef_A[0] ->[7]];
622/// [MemRef_A[0] ->[8]];
623/// [MemRef_A[0] ->[10]];
624/// [MemRef_A[0] ->[11]];
625/// [MemRef_A[1] ->[15]];
626/// [MemRef_A[1] ->[16]];
627/// [MemRef_A[1] ->[18]];
628/// [MemRef_A[1] ->[19]];
629/// [MemRef_A[1] ->[21]];
630/// [MemRef_A[1] ->[22]];
631/// [MemRef_A[1] ->[24]];
632/// [MemRef_A[1] ->[25]]
633/// }
634/// @{
635void dumpExpanded(const isl::set &Set);
636void dumpExpanded(const isl::map &Map);
637void dumpExpanded(const isl::union_set &USet);
638void dumpExpanded(const isl::union_map &UMap);
643/// @}
644} // namespace polly
645
646#endif /* POLLY_ISLTOOLS_H */
unsigned unsignedFromIslSize(const isl::size &Size)
Check that Size is valid (only on debug builds) and cast it to unsigned.
Definition: ISLTools.h:40
void islAssert(const isl::size &Size)
In debug builds assert that the Size is valid, in non-debug builds disable the mandatory state checki...
Definition: ISLTools.h:25
polly simplify
Definition: Simplify.cpp:853
bool operator==(const isl_iterator &O) const
Definition: ISLTools.h:64
ElementT operator*() const
Definition: ISLTools.h:79
isl_iterator(const ListT &List)
Definition: ISLTools.h:59
isl_iterator & operator++()
Definition: ISLTools.h:68
isl_iterator(const ListT &List, int Position)
Definition: ISLTools.h:61
isl_iterator operator++(int)
Definition: ISLTools.h:73
list_element_type< ListT > ElementT
Definition: ISLTools.h:57
bool is_error() const
#define __isl_keep
Definition: ctx.h:25
#define assert(exp)
t0 *a *b *t *a *b * t
Definition: jacobi_kernel4.c:2
struct isl_set isl_set
Definition: map_type.h:26
decltype(std::declval< ListT >().get_at(0)) list_element_type
Definition: ISLTools.h:49
isl_iterator< T > end(const T &t)
Definition: ISLTools.h:89
isl_iterator< T > begin(const T &t)
Definition: ISLTools.h:86
These are automatically generated checked C++ bindings for isl.
Definition: ISLTools.h:45
unsigned getNumScatterDims(const isl::union_map &Schedule)
Determine how many dimensions the scatter space of Schedule has.
Definition: ISLTools.cpp:163
isl::map betweenScatter(isl::map From, isl::map To, bool InclFrom, bool InclTo)
Construct a range of timepoints between two timepoints.
Definition: ISLTools.cpp:119
void dumpExpanded(const isl::set &Set)
Dump all points of the argument to llvm::errs().
Definition: ISLTools.cpp:889
isl::map beforeScatter(isl::map Map, bool Strict)
Return the range elements that are lexicographically smaller.
Definition: ISLTools.cpp:85
isl::union_map computeReachingWrite(isl::union_map Schedule, isl::union_map Writes, bool Reverse, bool InclPrevDef, bool InclNextDef)
Compute the reaching definition statement or the next overwrite for each definition of an array eleme...
Definition: ISLTools.cpp:313
isl::union_map computeArrayUnused(isl::union_map Schedule, isl::union_map Writes, isl::union_map Reads, bool ReadEltInSameInst, bool InclLastRead, bool InclWrite)
Compute the timepoints where the contents of an array element are not used.
Definition: ISLTools.cpp:366
isl::val getConstant(isl::pw_aff PwAff, bool Max, bool Min)
If PwAff maps to a constant, return said constant.
Definition: ISLTools.cpp:552
isl::map makeIdentityMap(const isl::set &Set, bool RestrictDomain)
Construct an identity map for the given domain values.
Definition: ISLTools.cpp:182
isl::map distributeDomain(isl::map Map)
Distribute the domain to the tuples of a wrapped range map.
Definition: ISLTools.cpp:455
llvm::iota_range< unsigned > rangeIslSize(unsigned Begin, isl::size End)
Check that End is valid and return an iterator from Begin to End.
Definition: ISLTools.cpp:597
isl::map reverseDomain(isl::map Map)
Reverse the nested map tuple in Map's domain.
Definition: ISLTools.cpp:199
isl::map subtractParams(isl::map Map, isl::set Params)
Subtract the parameter space Params from Map.
Definition: ISLTools.cpp:540
isl::map intersectRange(isl::map Map, isl::union_set Range)
Intersect the range of Map with Range.
Definition: ISLTools.cpp:535
isl::union_map liftDomains(isl::union_map UMap, isl::union_set Factor)
Prepend a space to the tuples of a map.
Definition: ISLTools.cpp:509
isl::union_map applyDomainRange(isl::union_map UMap, isl::union_map Func)
Apply a map to the 'middle' of another relation.
Definition: ISLTools.cpp:517
void dumpPw(const isl::set &Set)
Dump a description of the argument to llvm::errs().
Definition: ISLTools.cpp:857
isl::set shiftDim(isl::set Set, int Pos, int Amount)
Add a constant to one dimension of a set.
Definition: ISLTools.cpp:216
isl::union_set convertZoneToTimepoints(isl::union_set Zone, bool InclStart, bool InclEnd)
Convert a zone (range between timepoints) to timepoints.
Definition: ISLTools.cpp:410
isl::map afterScatter(isl::map Map, bool Strict)
Return the range elements that are lexicographically larger.
Definition: ISLTools.cpp:103
isl::map singleton(isl::union_map UMap, isl::space ExpectedSpace)
If by construction a union map is known to contain only a single map, return it.
Definition: ISLTools.cpp:135
isl::space getScatterSpace(const isl::union_map &Schedule)
Return the scatter space of a Schedule.
Definition: ISLTools.cpp:174
static TupleKindPtr Range("Range")
struct isl_union_set isl_union_set