58#include "llvm/ADT/Sequence.h"
59#include "llvm/ADT/Statistic.h"
60#include "llvm/Analysis/OptimizationRemarkEmitter.h"
61#include "llvm/Support/CommandLine.h"
73#define DEBUG_TYPE "polly-opt-isl"
75static cl::opt<std::string>
77 cl::desc(
"Only a certain kind of dependences (all/raw)"),
80static cl::opt<std::string>
82 cl::desc(
"Dependences should be simplified (yes/no)"),
86 "polly-opt-max-constant-term",
87 cl::desc(
"The maximal constant term allowed (-1 is unlimited)"), cl::Hidden,
91 "polly-opt-max-coefficient",
92 cl::desc(
"The maximal coefficient allowed (-1 is unlimited)"), cl::Hidden,
95static cl::opt<std::string>
97 cl::desc(
"Maximize the band depth (yes/no)"), cl::Hidden,
102 cl::desc(
"Bound the scheduler by maximal amount"
103 "of computational steps. "),
108 cl::desc(
"Aggressively try to fuse everything"), cl::Hidden,
112 "polly-opt-outer-coincidence",
113 cl::desc(
"Try to construct schedules where the outer member of each band "
114 "satisfies the coincidence constraints (yes/no)"),
118 "polly-prevect-width",
120 "The number of loop iterations to strip-mine for pre-vectorization"),
124 cl::desc(
"Enable loop tiling"),
128 "polly-default-tile-size",
129 cl::desc(
"The default tile size (if not enough were provided by"
130 " --polly-tile-sizes)"),
135 cl::desc(
"A tile size for each loop dimension, filled "
136 "with --polly-default-tile-size"),
141 cl::desc(
"Enable a 2nd level loop of loop tiling"),
145 "polly-2nd-level-default-tile-size",
146 cl::desc(
"The default 2nd-level tile size (if not enough were provided by"
147 " --polly-2nd-level-tile-sizes)"),
152 cl::desc(
"A tile size for each loop dimension, filled "
153 "with --polly-default-tile-size"),
154 cl::Hidden, cl::CommaSeparated,
158 cl::desc(
"Enable register tiling"),
162 "polly-register-tiling-default-tile-size",
163 cl::desc(
"The default register tile size (if not enough were provided by"
164 " --polly-register-tile-sizes)"),
169 cl::desc(
"A tile size for each loop dimension, filled "
170 "with --polly-register-tile-size"),
174 "polly-pragma-based-opts",
175 cl::desc(
"Apply user-directed transformation from metadata"),
179 cl::desc(
"Optimize SCoPs using ISL"),
184 cl::desc(
"Perform optimizations based on pattern matching"),
189 cl::desc(
"Apply post-rescheduling optimizations such as "
190 "tiling (requires -polly-reschedule)"),
194 "polly-optimized-scops",
195 cl::desc(
"Polly - Dump polyhedral description of Scops optimized with "
196 "the isl scheduling optimizer and the set of post-scheduling "
197 "transformations is applied on the schedule tree"),
201 cl::desc(
"A polly pass"),
205STATISTIC(ScopsRescheduled,
"Number of scops rescheduled");
208STATISTIC(NumAffineLoopsOptimized,
"Number of affine loops optimized");
209STATISTIC(NumBoxedLoopsOptimized,
"Number of boxed loops optimized");
211#define THREE_STATISTICS(VARNAME, DESC) \
212 static Statistic VARNAME[3] = { \
213 {DEBUG_TYPE, #VARNAME "0", DESC " (original)"}, \
214 {DEBUG_TYPE, #VARNAME "1", DESC " (after scheduler)"}, \
215 {DEBUG_TYPE, #VARNAME "2", DESC " (after optimizer)"}}
224STATISTIC(FirstLevelTileOpts,
"Number of first level tiling applied");
225STATISTIC(SecondLevelTileOpts,
"Number of second level tiling applied");
226STATISTIC(RegisterTileOpts,
"Number of register tiling applied");
227STATISTIC(PrevectOpts,
"Number of strip-mining for prevectorization applied");
229 "Number of matrix multiplication patterns detected and optimized");
236struct OptimizerAdditionalInfoTy {
237 const llvm::TargetTransformInfo *TTI;
246class ScheduleTreeOptimizer final {
263 optimizeSchedule(isl::schedule Schedule,
264 const OptimizerAdditionalInfoTy *OAI =
nullptr);
279 static isl::schedule_node
280 optimizeScheduleNode(isl::schedule_node Node,
281 const OptimizerAdditionalInfoTy *OAI =
nullptr);
289 static bool isProfitableSchedule(polly::Scop &
S, isl::schedule NewSchedule);
299 static isl::schedule_node isolateFullPartialTiles(isl::schedule_node Node,
309 static bool isTileableBandNode(isl::schedule_node Node);
319 static bool isPMOptimizableBandNode(isl::schedule_node Node);
352 static isl::schedule_node prevectSchedBand(isl::schedule_node Node,
353 unsigned DimToVectorize,
377 static isl::schedule_node applyTileBandOpt(isl::schedule_node Node);
382 static isl::schedule_node applyPrevectBandOpt(isl::schedule_node Node);
386ScheduleTreeOptimizer::isolateFullPartialTiles(isl::schedule_node Node,
392 isl::union_map SchedRelUMap = Node.get_prefix_schedule_relation();
393 isl::union_set ScheduleRangeUSet = SchedRelUMap.
range();
394 isl::set ScheduleRange{ScheduleRangeUSet};
399 isl::union_set Options = IsolateOption.
unite(AtomicOption);
402 isl::schedule_node_band Result =
403 Node.
as<isl::schedule_node_band>().set_ast_build_options(Options);
407struct InsertSimdMarkers final : ScheduleNodeRewriter<InsertSimdMarkers> {
408 isl::schedule_node visitBand(isl::schedule_node_band Band) {
409 isl::schedule_node Node = visitChildren(Band);
420isl::schedule_node ScheduleTreeOptimizer::prevectSchedBand(
421 isl::schedule_node Node,
unsigned DimToVectorize,
int VectorWidth) {
430 assert(DimToVectorize < ScheduleDimensions);
432 if (DimToVectorize > 0) {
435 Node = Node.
child(0);
437 if (DimToVectorize < ScheduleDimensions - 1)
441 Sizes = Sizes.set_val(0, isl::val(Node.
ctx(), VectorWidth));
444 Node = isolateFullPartialTiles(Node, VectorWidth);
445 Node = Node.
child(0);
448 Node = Node.
as<isl::schedule_node_band>().set_ast_build_options(
449 isl::union_set(Node.
ctx(),
"{ unroll[x]: 1 = 0 }"));
458 InsertSimdMarkers SimdMarkerInserter;
459 Node = SimdMarkerInserter.visit(Node);
466static bool isSimpleInnermostBand(
const isl::schedule_node &Node) {
478 auto Sequence = Node.
child(0);
482 auto Child = Sequence.child(c);
495static bool isOneTimeParentBandNode(isl::schedule_node Node) {
505bool ScheduleTreeOptimizer::isTileableBandNode(isl::schedule_node Node) {
506 if (!isOneTimeParentBandNode(Node))
517 return isSimpleInnermostBand(Node);
520bool ScheduleTreeOptimizer::isPMOptimizableBandNode(isl::schedule_node Node) {
521 if (!isOneTimeParentBandNode(Node))
524 return Node.
child(0).
isa<isl::schedule_node_leaf>();
528ScheduleTreeOptimizer::applyTileBandOpt(isl::schedule_node Node) {
532 FirstLevelTileOpts++;
538 SecondLevelTileOpts++;
551ScheduleTreeOptimizer::applyPrevectBandOpt(isl::schedule_node Node) {
557 for (
int i = Dims - 1; i >= 0; i--)
558 if (Node.
as<isl::schedule_node_band>().member_get_coincident(i)) {
569 const OptimizerAdditionalInfoTy *OAI =
570 static_cast<const OptimizerAdditionalInfoTy *
>(User);
571 assert(OAI &&
"Expecting optimization options");
575 if (OAI->PatternOpts && isPMOptimizableBandNode(Node)) {
576 isl::schedule_node PatternOptimizedSchedule =
578 if (!PatternOptimizedSchedule.
is_null()) {
580 OAI->DepsChanged =
true;
581 return PatternOptimizedSchedule.
release();
585 if (!isTileableBandNode(Node))
589 Node = applyTileBandOpt(Node);
592 IslQuotaScope MaxScope = OAI->MaxOpGuard.
enter();
596 Node = applyPrevectBandOpt(Node);
599 return (isl::schedule_node()).release();
606ScheduleTreeOptimizer::optimizeSchedule(isl::schedule Schedule,
607 const OptimizerAdditionalInfoTy *OAI) {
609 Root = optimizeScheduleNode(Root, OAI);
610 return Root.get_schedule();
613isl::schedule_node ScheduleTreeOptimizer::optimizeScheduleNode(
614 isl::schedule_node Node,
const OptimizerAdditionalInfoTy *OAI) {
617 const_cast<void *
>(
static_cast<const void *
>(OAI))));
621bool ScheduleTreeOptimizer::isProfitableSchedule(Scop &
S,
622 isl::schedule NewSchedule) {
635 auto NewScheduleMap = NewSchedule.
get_map();
636 auto OldSchedule =
S.getSchedule();
637 assert(!OldSchedule.is_null() &&
638 "Only IslScheduleOptimizer can insert extension nodes "
639 "that make Scop::getSchedule() return nullptr.");
640 bool changed = !OldSchedule.is_equal(NewScheduleMap);
645static void printSchedule(llvm::raw_ostream &OS,
const isl::schedule &Schedule,
647 isl::ctx
Ctx = Schedule.
ctx();
652 OS << Desc <<
": \n" <<
Str <<
"\n";
660static bool hasBoundedDistances(
const isl::map &Map) {
662 return !Deltas.
is_null() && Deltas.is_bounded().is_true();
678static isl::union_map keepBoundedDistances(
const isl::union_map &Simplified,
679 const isl::union_map &Exact) {
690 if (!hasBoundedDistances(Bounded))
692 if (hasBoundedDistances(Bounded))
695 Result = Result.
unite(isl::union_map(Map));
709static void walkScheduleTreeForStatistics(isl::schedule Schedule,
int Version) {
717 isl::schedule_node Node = isl::manage_copy(nodeptr);
718 int Version = *static_cast<int *>(user);
720 switch (isl_schedule_node_get_type(Node.get())) {
721 case isl_schedule_node_band: {
723 if (isl_schedule_node_band_get_permutable(Node.get()) ==
725 NumPermutable[Version]++;
727 int CountMembers = isl_schedule_node_band_n_member(Node.get());
728 NumBandMembers[Version] += CountMembers;
729 for (int i = 0; i < CountMembers; i += 1) {
730 if (Node.as<isl::schedule_node_band>().member_get_coincident(i))
731 NumCoincident[Version]++;
736 case isl_schedule_node_filter:
737 NumFilters[Version]++;
740 case isl_schedule_node_extension:
741 NumExtension[Version]++;
753static void runIslScheduleOptimizerImpl(
756 TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE,
760 if (
S.getSize() == 0) {
769 walkScheduleTreeForStatistics(
S.getScheduleTree(), 0);
770 POLLY_DEBUG(printSchedule(dbgs(), Schedule,
"Original schedule tree"));
772 bool HasUserTransformation =
false;
776 if (ManuallyTransformed.
is_null()) {
777 POLLY_DEBUG(dbgs() <<
"Error during manual optimization\n");
781 if (ManuallyTransformed.
get() != Schedule.
get()) {
783 HasUserTransformation =
true;
784 Schedule = std::move(ManuallyTransformed);
786 printSchedule(dbgs(), Schedule,
"After manual transformations"));
794 if (!HasUserTransformation &&
S.hasDisableHeuristicsHint()) {
795 POLLY_DEBUG(dbgs() <<
"Heuristic optimizations disabled by metadata\n");
802 POLLY_DEBUG(dbgs() <<
"DependenceInfo for another SCoP/isl_ctx\n");
806 POLLY_DEBUG(dbgs() <<
"Dependency information not available\n");
820 POLLY_DEBUG(dbgs() <<
"Skipping rescheduling due to command line option\n");
821 }
else if (HasUserTransformation) {
823 dbgs() <<
"Skipping rescheduling due to manual transformation\n");
836 errs() <<
"Do not know how to optimize for '" <<
OptimizeDeps <<
"'"
837 <<
" Falling back to optimizing all dependences.\n";
863 Proximity = keepBoundedDistances(Proximity, ExactProximity);
866 <<
"warning: Option -polly-opt-simplify-deps should either be 'yes' "
867 "or 'no'. Falling back to default: 'yes'\n";
870 POLLY_DEBUG(dbgs() <<
"\n\nCompute schedule from: ");
872 POLLY_DEBUG(dbgs() <<
"Proximity := " << Proximity <<
";\n");
873 POLLY_DEBUG(dbgs() <<
"Validity := " << Validity <<
";\n");
875 int IslMaximizeBands;
877 IslMaximizeBands = 1;
879 IslMaximizeBands = 0;
882 <<
"warning: Option -polly-opt-maximize-bands should either be 'yes'"
883 " or 'no'. Falling back to default: 'yes'\n";
884 IslMaximizeBands = 1;
887 int IslOuterCoincidence;
889 IslOuterCoincidence = 1;
891 IslOuterCoincidence = 0;
893 errs() <<
"warning: Option -polly-opt-outer-coincidence should either be "
894 "'yes' or 'no'. Falling back to default: 'no'\n";
895 IslOuterCoincidence = 0;
908 SC = SC.set_proximity(Proximity);
909 SC = SC.set_validity(Validity);
910 SC = SC.set_coincidence(Validity);
914 Schedule = SC.compute_schedule();
921 POLLY_DEBUG(printSchedule(dbgs(), Schedule,
"After rescheduling"));
924 walkScheduleTreeForStatistics(Schedule, 1);
934 const OptimizerAdditionalInfoTy OAI = {
942 if (!Schedule.
is_null() && (OAI.PatternOpts || OAI.Postopts || OAI.Prevect)) {
943 Schedule = ScheduleTreeOptimizer::optimizeSchedule(Schedule, &OAI);
945 POLLY_DEBUG(printSchedule(dbgs(), Schedule,
"After post-optimizations"));
946 walkScheduleTreeForStatistics(Schedule, 2);
950 if (MaxOpGuard.hasQuotaExceeded()) {
951 POLLY_DEBUG(dbgs() <<
"Schedule optimizer calculation exceeds ISL quota\n");
958 dbgs() <<
"ISL reported an error during the computation of a new "
960 << File <<
":" << Line <<
": " << Msg;
964 }
else if (Schedule.
is_null()) {
965 POLLY_DEBUG(dbgs() <<
"Schedule optimizer did not compute a new schedule "
966 "for unknown reasons\n");
971 if (!HasUserTransformation &&
972 !ScheduleTreeOptimizer::isProfitableSchedule(
S, Schedule))
975 auto ScopStats =
S.getStatistics();
977 NumAffineLoopsOptimized += ScopStats.NumAffineLoops;
978 NumBoxedLoopsOptimized += ScopStats.NumBoxedLoops;
979 LastSchedule = Schedule;
981 S.setScheduleTree(Schedule);
988static void runScheduleOptimizerPrinter(raw_ostream &OS,
993 OS <<
"Calculated schedule:\n";
1006 OS << ScheduleStr <<
"\n";
1018 OptimizationRemarkEmitter ORE(&
S.getFunction());
1020 bool DepsChanged =
false;
1021 runIslScheduleOptimizerImpl(
S, GetDeps, TTI, &ORE, LastSchedule, DepsChanged);
1027 <<
"Printing analysis 'Polly - Optimize schedule of SCoP' for region: '"
1028 <<
S.getName() <<
"' in function '" <<
S.getFunction().getName()
1030 runScheduleOptimizerPrinter(outs(), LastSchedule);
llvm::cl::OptionCategory PollyCategory
static cl::opt< bool > PragmaBasedOpts("polly-pragma-based-opts", cl::desc("Apply user-directed transformation from metadata"), cl::init(true), cl::cat(PollyCategory))
static cl::opt< int > MaxCoefficient("polly-opt-max-coefficient", cl::desc("The maximal coefficient allowed (-1 is unlimited)"), cl::Hidden, cl::init(20), cl::cat(PollyCategory))
static cl::opt< bool > PollyPrintOptIsl("polly-print-opt-isl", cl::desc("A polly pass"), cl::cat(PollyCategory))
static cl::opt< int > MaxConstantTerm("polly-opt-max-constant-term", cl::desc("The maximal constant term allowed (-1 is unlimited)"), cl::Hidden, cl::init(20), cl::cat(PollyCategory))
static cl::opt< int > PrevectorWidth("polly-prevect-width", cl::desc("The number of loop iterations to strip-mine for pre-vectorization"), cl::Hidden, cl::init(4), cl::cat(PollyCategory))
static cl::opt< std::string > MaximizeBandDepth("polly-opt-maximize-bands", cl::desc("Maximize the band depth (yes/no)"), cl::Hidden, cl::init("yes"), cl::cat(PollyCategory))
static cl::opt< int > ScheduleComputeOut("polly-schedule-computeout", cl::desc("Bound the scheduler by maximal amount" "of computational steps. "), cl::Hidden, cl::init(300000), cl::cat(PollyCategory))
static cl::opt< int > SecondLevelDefaultTileSize("polly-2nd-level-default-tile-size", cl::desc("The default 2nd-level tile size (if not enough were provided by" " --polly-2nd-level-tile-sizes)"), cl::Hidden, cl::init(16), cl::cat(PollyCategory))
static cl::opt< int > RegisterDefaultTileSize("polly-register-tiling-default-tile-size", cl::desc("The default register tile size (if not enough were provided by" " --polly-register-tile-sizes)"), cl::Hidden, cl::init(2), cl::cat(PollyCategory))
static cl::opt< int > FirstLevelDefaultTileSize("polly-default-tile-size", cl::desc("The default tile size (if not enough were provided by" " --polly-tile-sizes)"), cl::Hidden, cl::init(32), cl::cat(PollyCategory))
static cl::opt< bool > OptimizedScops("polly-optimized-scops", cl::desc("Polly - Dump polyhedral description of Scops optimized with " "the isl scheduling optimizer and the set of post-scheduling " "transformations is applied on the schedule tree"), cl::cat(PollyCategory))
static cl::opt< bool > PMBasedOpts("polly-pattern-matching-based-opts", cl::desc("Perform optimizations based on pattern matching"), cl::init(true), cl::cat(PollyCategory))
static cl::opt< bool > EnablePostopts("polly-postopts", cl::desc("Apply post-rescheduling optimizations such as " "tiling (requires -polly-reschedule)"), cl::init(true), cl::cat(PollyCategory))
static cl::opt< bool > FirstLevelTiling("polly-tiling", cl::desc("Enable loop tiling"), cl::init(true), cl::cat(PollyCategory))
static cl::list< int > FirstLevelTileSizes("polly-tile-sizes", cl::desc("A tile size for each loop dimension, filled " "with --polly-default-tile-size"), cl::Hidden, cl::CommaSeparated, cl::cat(PollyCategory))
static cl::opt< bool > GreedyFusion("polly-loopfusion-greedy", cl::desc("Aggressively try to fuse everything"), cl::Hidden, cl::cat(PollyCategory))
static cl::opt< bool > RegisterTiling("polly-register-tiling", cl::desc("Enable register tiling"), cl::cat(PollyCategory))
static cl::opt< std::string > SimplifyDeps("polly-opt-simplify-deps", cl::desc("Dependences should be simplified (yes/no)"), cl::Hidden, cl::init("yes"), cl::cat(PollyCategory))
static cl::opt< bool > EnableReschedule("polly-reschedule", cl::desc("Optimize SCoPs using ISL"), cl::init(true), cl::cat(PollyCategory))
STATISTIC(ScopsProcessed, "Number of scops processed")
static cl::opt< bool > SecondLevelTiling("polly-2nd-level-tiling", cl::desc("Enable a 2nd level loop of loop tiling"), cl::cat(PollyCategory))
static cl::opt< std::string > OptimizeDeps("polly-opt-optimize-only", cl::desc("Only a certain kind of dependences (all/raw)"), cl::Hidden, cl::init("all"), cl::cat(PollyCategory))
static cl::list< int > RegisterTileSizes("polly-register-tile-sizes", cl::desc("A tile size for each loop dimension, filled " "with --polly-register-tile-size"), cl::Hidden, cl::CommaSeparated, cl::cat(PollyCategory))
#define THREE_STATISTICS(VARNAME, DESC)
static cl::list< int > SecondLevelTileSizes("polly-2nd-level-tile-sizes", cl::desc("A tile size for each loop dimension, filled " "with --polly-default-tile-size"), cl::Hidden, cl::CommaSeparated, cl::cat(PollyCategory))
static cl::opt< std::string > OuterCoincidence("polly-opt-outer-coincidence", cl::desc("Try to construct schedules where the outer member of each band " "satisfies the coincidence constraints (yes/no)"), cl::Hidden, cl::init("no"), cl::cat(PollyCategory))
isl::checked::set deltas() const
isl::checked::space get_space() const
isl::checked::map intersect(isl::checked::map map2) const
isl::checked::ctx ctx() const
isl::checked::ctx ctx() const
isl::checked::schedule_node child(int pos) const
__isl_give isl_schedule_node * release()
isl::checked::schedule_node parent() const
isl::checked::schedule_node first_child() const
isl::checked::schedule_node insert_mark(isl::checked::id mark) const
__isl_keep isl_schedule_node * get() const
__isl_keep isl_schedule * get() const
isl::checked::schedule_node get_root() const
isl::checked::union_map get_map() const
isl::checked::ctx ctx() const
isl::checked::ctx ctx() const
isl::checked::map translation() const
isl::checked::space domain() const
isl::checked::space range() const
boolean is_equal(const isl::checked::space &space2) const
isl::checked::union_set range() const
isl::checked::union_map unite(isl::checked::union_map umap2) const
isl::checked::map extract_map(isl::checked::space space) const
isl::checked::map_list get_map_list() const
isl::checked::ctx ctx() const
isl::checked::union_map gist_range(isl::checked::union_set uset) const
isl::checked::union_map gist_domain(isl::checked::union_set uset) const
isl::checked::union_set unite(isl::checked::union_set uset2) const
static isl::id alloc(isl::ctx ctx, const std::string &name, void *user)
static isl::multi_val zero(isl::space space)
static isl::schedule_constraints on_domain(isl::union_set domain)
static isl::union_map empty(isl::ctx ctx)
The accumulated dependence information for a SCoP.
bool hasValidDependences() const
Report if valid dependences are available.
const std::shared_ptr< isl_ctx > & getSharedIslCtx() const
isl::union_map getDependences(int Kinds) const
Get the dependences of type Kinds.
Scoped limit of ISL operations.
bool hasQuotaExceeded() const
Return whether the current quota has exceeded.
IslQuotaScope enter(bool AllowReturnNull=true)
Enter a scope that can handle out-of-quota errors.
Scope guard for code that allows arbitrary isl function to return an error if the max-operations quot...
const char * isl_ctx_last_error_file(isl_ctx *ctx)
enum isl_error isl_ctx_last_error(isl_ctx *ctx)
void isl_ctx_reset_error(isl_ctx *ctx)
int isl_ctx_last_error_line(isl_ctx *ctx)
const char * isl_ctx_last_error_msg(isl_ctx *ctx)
isl_stat isl_stat void * user
enum isl_schedule_node_type isl_schedule_node_get_type(__isl_keep isl_schedule_node *node)
boolean manage(isl_bool val)
isl::schedule applyManualTransformations(Scop *S, isl::schedule Sched, const Dependences &D, llvm::OptimizationRemarkEmitter *ORE)
Apply loop-transformation metadata.
VectorizerChoice PollyVectorizerChoice
isl::schedule_node applyRegisterTiling(isl::schedule_node Node, llvm::ArrayRef< int > TileSizes, int DefaultTileSize)
Tile a schedule node and unroll point loops.
isl::schedule applyGreedyFusion(isl::schedule Sched, const isl::union_map &Deps)
Apply greedy fusion.
isl::schedule_node tryOptimizeMatMulPattern(isl::schedule_node Node, const llvm::TargetTransformInfo *TTI, const Dependences *D)
Apply the BLIS matmul optimization pattern if possible.
isl::union_set getIsolateOptions(isl::set IsolateDomain, unsigned OutDimsNum)
Create an isl::union_set, which describes the isolate option based on IsolateDomain.
void runIslScheduleOptimizer(Scop &S, llvm::TargetTransformInfo *TTI, DependenceAnalysis::Result &Deps)
isl::schedule_node tileNode(isl::schedule_node Node, const char *Identifier, llvm::ArrayRef< int > TileSizes, int DefaultTileSize)
Tile a schedule node.
isl::union_set getDimOptions(isl::ctx Ctx, const char *Option)
Create an isl::union_set, which describes the specified option for the dimension of the current node.
isl::schedule hoistExtensionNodes(isl::schedule Sched)
Hoist all domains from extension into the root domain node, such that there are no more extension nod...
isl::set getPartialTilePrefixes(isl::set ScheduleRange, int VectorWidth)
Build the desired set of partial tile prefixes.
isl_stat isl_options_set_on_error(isl_ctx *ctx, int val)
int isl_options_get_on_error(isl_ctx *ctx)
#define ISL_ON_ERROR_CONTINUE
__isl_null isl_printer * isl_printer_free(__isl_take isl_printer *printer)
__isl_give char * isl_printer_get_str(__isl_keep isl_printer *printer)
#define ISL_YAML_STYLE_BLOCK
__isl_give isl_printer * isl_printer_set_yaml_style(__isl_take isl_printer *p, int yaml_style)
__isl_give isl_printer * isl_printer_to_str(isl_ctx *ctx)
struct isl_printer isl_printer
isl_stat isl_options_set_schedule_outer_coincidence(isl_ctx *ctx, int val)
isl_stat isl_options_set_schedule_maximize_band_depth(isl_ctx *ctx, int val)
__isl_give isl_printer * isl_printer_print_schedule(__isl_take isl_printer *p, __isl_keep isl_schedule *schedule)
isl_stat isl_options_set_schedule_max_constant_term(isl_ctx *ctx, int val)
isl_stat isl_options_set_schedule_max_coefficient(isl_ctx *ctx, int val)
__isl_give isl_schedule_node * isl_schedule_node_band_sink(__isl_take isl_schedule_node *node)
__isl_export __isl_give isl_schedule_node * isl_schedule_node_band_split(__isl_take isl_schedule_node *node, int pos)
__isl_export isl_size isl_schedule_node_n_children(__isl_keep isl_schedule_node *node)
__isl_export __isl_give isl_schedule_node * isl_schedule_node_band_tile(__isl_take isl_schedule_node *node, __isl_take isl_multi_val *sizes)
__isl_export isl_stat isl_schedule_node_foreach_descendant_top_down(__isl_keep isl_schedule_node *node, isl_bool(*fn)(__isl_keep isl_schedule_node *node, void *user), void *user)
__isl_give isl_space * isl_schedule_node_band_get_space(__isl_keep isl_schedule_node *node)
__isl_export __isl_give isl_schedule_node * isl_schedule_node_map_descendant_bottom_up(__isl_take isl_schedule_node *node, __isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node, void *user), void *user)
isl_stat isl_options_set_tile_scale_tile_loops(isl_ctx *ctx, int val)
__isl_export isl_bool isl_schedule_node_band_get_permutable(__isl_keep isl_schedule_node *node)
struct isl_schedule_node isl_schedule_node
@ isl_schedule_node_filter
@ isl_schedule_node_sequence
const Dependences & getDependences(Dependences::AnalysisLevel Level)
Return the dependence information for the current SCoP.
void abandonDependences()
Invalidate the dependence information and recompute it when needed again.
static TupleKindPtr Domain("Domain")