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-isolate-complete-tiles",
175 cl::desc(
"Separate the complete tiles of a tiled band from the partial "
176 "ones, so that the point loops of the complete tiles have "
181 "polly-isolate-complete-tile-dims",
182 cl::desc(
"Number of innermost tile dimensions that have to be complete for "
183 "a tile to be isolated (0: all of them). Requiring fewer of them "
184 "generates less code, but also gives fewer point loops a constant "
189 "polly-isolate-complete-tiles-2nd-level",
190 cl::desc(
"Separate the complete tiles of the second level of tiling from "
195 "polly-isolate-complete-register-tiles",
196 cl::desc(
"Separate the complete register tiles from the partial ones, so "
197 "that their unrolled point loops need no guards"),
201 "polly-pragma-based-opts",
202 cl::desc(
"Apply user-directed transformation from metadata"),
206 cl::desc(
"Optimize SCoPs using ISL"),
211 cl::desc(
"Perform optimizations based on pattern matching"),
216 cl::desc(
"Apply post-rescheduling optimizations such as "
217 "tiling (requires -polly-reschedule)"),
221 "polly-optimized-scops",
222 cl::desc(
"Polly - Dump polyhedral description of Scops optimized with "
223 "the isl scheduling optimizer and the set of post-scheduling "
224 "transformations is applied on the schedule tree"),
228 cl::desc(
"A polly pass"),
232STATISTIC(ScopsRescheduled,
"Number of scops rescheduled");
235STATISTIC(NumAffineLoopsOptimized,
"Number of affine loops optimized");
236STATISTIC(NumBoxedLoopsOptimized,
"Number of boxed loops optimized");
238#define THREE_STATISTICS(VARNAME, DESC) \
239 static Statistic VARNAME[3] = { \
240 {DEBUG_TYPE, #VARNAME "0", DESC " (original)"}, \
241 {DEBUG_TYPE, #VARNAME "1", DESC " (after scheduler)"}, \
242 {DEBUG_TYPE, #VARNAME "2", DESC " (after optimizer)"}}
251STATISTIC(FirstLevelTileOpts,
"Number of first level tiling applied");
252STATISTIC(SecondLevelTileOpts,
"Number of second level tiling applied");
253STATISTIC(RegisterTileOpts,
"Number of register tiling applied");
254STATISTIC(PrevectOpts,
"Number of strip-mining for prevectorization applied");
256 "Number of matrix multiplication patterns detected and optimized");
263struct OptimizerAdditionalInfoTy {
264 const llvm::TargetTransformInfo *TTI;
273class ScheduleTreeOptimizer final {
290 optimizeSchedule(isl::schedule Schedule,
291 const OptimizerAdditionalInfoTy *OAI =
nullptr);
306 static isl::schedule_node
307 optimizeScheduleNode(isl::schedule_node Node,
308 const OptimizerAdditionalInfoTy *OAI =
nullptr);
316 static bool isProfitableSchedule(polly::Scop &
S, isl::schedule NewSchedule);
326 static isl::schedule_node isolateFullPartialTiles(isl::schedule_node Node,
336 static bool isTileableBandNode(isl::schedule_node Node);
346 static bool isPMOptimizableBandNode(isl::schedule_node Node);
379 static isl::schedule_node prevectSchedBand(isl::schedule_node Node,
380 unsigned DimToVectorize,
404 static isl::schedule_node applyTileBandOpt(isl::schedule_node Node);
409 static isl::schedule_node applyPrevectBandOpt(isl::schedule_node Node);
413ScheduleTreeOptimizer::isolateFullPartialTiles(isl::schedule_node Node,
419 isl::union_map SchedRelUMap = Node.get_prefix_schedule_relation();
420 isl::union_set ScheduleRangeUSet = SchedRelUMap.
range();
421 isl::set ScheduleRange{ScheduleRangeUSet};
426 isl::union_set Options = IsolateOption.
unite(AtomicOption);
429 isl::schedule_node_band Result =
430 Node.
as<isl::schedule_node_band>().set_ast_build_options(Options);
445static isl::schedule_node isolateCompleteTiles(isl::schedule_node Node,
446 ArrayRef<int> TileSizes) {
448 "Expecting the point band that tileNode returned");
452 isl::union_set ScheduleRangeUSet =
453 Node.
child(0).get_prefix_schedule_relation().range();
454 isl::set ScheduleRange{ScheduleRangeUSet};
458 unsigned NumCompleteDims = TileSizes.size();
465 if (CompleteTilePrefixes.
is_null())
468 isl::union_set Options =
475 if (!TileBand.
isa<isl::schedule_node_band>())
479 TileBand.
as<isl::schedule_node_band>().set_ast_build_options(Options);
486struct InsertSimdMarkers final : ScheduleNodeRewriter<InsertSimdMarkers> {
487 isl::schedule_node visitBand(isl::schedule_node_band Band) {
488 isl::schedule_node Node = visitChildren(Band);
499isl::schedule_node ScheduleTreeOptimizer::prevectSchedBand(
500 isl::schedule_node Node,
unsigned DimToVectorize,
int VectorWidth) {
509 assert(DimToVectorize < ScheduleDimensions);
511 if (DimToVectorize > 0) {
514 Node = Node.
child(0);
516 if (DimToVectorize < ScheduleDimensions - 1)
520 Sizes = Sizes.set_val(0, isl::val(Node.
ctx(), VectorWidth));
523 Node = isolateFullPartialTiles(Node, VectorWidth);
524 Node = Node.
child(0);
527 Node = Node.
as<isl::schedule_node_band>().set_ast_build_options(
528 isl::union_set(Node.
ctx(),
"{ unroll[x]: 1 = 0 }"));
537 InsertSimdMarkers SimdMarkerInserter;
538 Node = SimdMarkerInserter.visit(Node);
545static bool isSimpleInnermostBand(
const isl::schedule_node &Node) {
557 auto Sequence = Node.
child(0);
561 auto Child = Sequence.child(c);
574static bool isOneTimeParentBandNode(isl::schedule_node Node) {
584bool ScheduleTreeOptimizer::isTileableBandNode(isl::schedule_node Node) {
585 if (!isOneTimeParentBandNode(Node))
596 return isSimpleInnermostBand(Node);
599bool ScheduleTreeOptimizer::isPMOptimizableBandNode(isl::schedule_node Node) {
600 if (!isOneTimeParentBandNode(Node))
603 return Node.
child(0).
isa<isl::schedule_node_leaf>();
607static SmallVector<int, 4> resolveTileSizes(isl::schedule_node Node,
608 ArrayRef<int> TileSizes,
609 int DefaultTileSize) {
610 SmallVector<int, 4> Sizes;
613 Sizes.push_back(i < TileSizes.size() ? TileSizes[i] : DefaultTileSize);
618ScheduleTreeOptimizer::applyTileBandOpt(isl::schedule_node Node) {
621 SmallVector<int, 4> Sizes;
628 FirstLevelTileOpts++;
631 Node = isolateCompleteTiles(Node, Sizes);
635 SmallVector<int, 4> Sizes;
641 SecondLevelTileOpts++;
643 Node = isolateCompleteTiles(Node, Sizes);
647 SmallVector<int, 4> Sizes;
655 Node = isolateCompleteTiles(Node, Sizes);
662ScheduleTreeOptimizer::applyPrevectBandOpt(isl::schedule_node Node) {
668 for (
int i = Dims - 1; i >= 0; i--)
669 if (Node.
as<isl::schedule_node_band>().member_get_coincident(i)) {
680 const OptimizerAdditionalInfoTy *OAI =
681 static_cast<const OptimizerAdditionalInfoTy *
>(User);
682 assert(OAI &&
"Expecting optimization options");
686 if (OAI->PatternOpts && isPMOptimizableBandNode(Node)) {
687 isl::schedule_node PatternOptimizedSchedule =
689 if (!PatternOptimizedSchedule.
is_null()) {
691 OAI->DepsChanged =
true;
692 return PatternOptimizedSchedule.
release();
696 if (!isTileableBandNode(Node))
700 Node = applyTileBandOpt(Node);
703 IslQuotaScope MaxScope = OAI->MaxOpGuard.
enter();
707 Node = applyPrevectBandOpt(Node);
710 return (isl::schedule_node()).release();
717ScheduleTreeOptimizer::optimizeSchedule(isl::schedule Schedule,
718 const OptimizerAdditionalInfoTy *OAI) {
720 Root = optimizeScheduleNode(Root, OAI);
721 return Root.get_schedule();
724isl::schedule_node ScheduleTreeOptimizer::optimizeScheduleNode(
725 isl::schedule_node Node,
const OptimizerAdditionalInfoTy *OAI) {
728 const_cast<void *
>(
static_cast<const void *
>(OAI))));
732bool ScheduleTreeOptimizer::isProfitableSchedule(Scop &
S,
733 isl::schedule NewSchedule) {
746 auto NewScheduleMap = NewSchedule.
get_map();
747 auto OldSchedule =
S.getSchedule();
748 assert(!OldSchedule.is_null() &&
749 "Only IslScheduleOptimizer can insert extension nodes "
750 "that make Scop::getSchedule() return nullptr.");
751 bool changed = !OldSchedule.is_equal(NewScheduleMap);
756static void printSchedule(llvm::raw_ostream &OS,
const isl::schedule &Schedule,
758 isl::ctx
Ctx = Schedule.
ctx();
763 OS << Desc <<
": \n" <<
Str <<
"\n";
771static bool hasBoundedDistances(
const isl::map &Map) {
773 return !Deltas.
is_null() && Deltas.is_bounded().is_true();
789static isl::union_map keepBoundedDistances(
const isl::union_map &Simplified,
790 const isl::union_map &Exact) {
801 if (!hasBoundedDistances(Bounded))
803 if (hasBoundedDistances(Bounded))
806 Result = Result.
unite(isl::union_map(Map));
820static void walkScheduleTreeForStatistics(isl::schedule Schedule,
int Version) {
828 isl::schedule_node Node = isl::manage_copy(nodeptr);
829 int Version = *static_cast<int *>(user);
831 switch (isl_schedule_node_get_type(Node.get())) {
832 case isl_schedule_node_band: {
834 if (isl_schedule_node_band_get_permutable(Node.get()) ==
836 NumPermutable[Version]++;
838 int CountMembers = isl_schedule_node_band_n_member(Node.get());
839 NumBandMembers[Version] += CountMembers;
840 for (int i = 0; i < CountMembers; i += 1) {
841 if (Node.as<isl::schedule_node_band>().member_get_coincident(i))
842 NumCoincident[Version]++;
847 case isl_schedule_node_filter:
848 NumFilters[Version]++;
851 case isl_schedule_node_extension:
852 NumExtension[Version]++;
864static void runIslScheduleOptimizerImpl(
867 TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE,
871 if (
S.getSize() == 0) {
880 walkScheduleTreeForStatistics(
S.getScheduleTree(), 0);
881 POLLY_DEBUG(printSchedule(dbgs(), Schedule,
"Original schedule tree"));
883 bool HasUserTransformation =
false;
887 if (ManuallyTransformed.
is_null()) {
888 POLLY_DEBUG(dbgs() <<
"Error during manual optimization\n");
892 if (ManuallyTransformed.
get() != Schedule.
get()) {
894 HasUserTransformation =
true;
895 Schedule = std::move(ManuallyTransformed);
897 printSchedule(dbgs(), Schedule,
"After manual transformations"));
905 if (!HasUserTransformation &&
S.hasDisableHeuristicsHint()) {
906 POLLY_DEBUG(dbgs() <<
"Heuristic optimizations disabled by metadata\n");
913 POLLY_DEBUG(dbgs() <<
"DependenceInfo for another SCoP/isl_ctx\n");
917 POLLY_DEBUG(dbgs() <<
"Dependency information not available\n");
931 POLLY_DEBUG(dbgs() <<
"Skipping rescheduling due to command line option\n");
932 }
else if (HasUserTransformation) {
934 dbgs() <<
"Skipping rescheduling due to manual transformation\n");
947 errs() <<
"Do not know how to optimize for '" <<
OptimizeDeps <<
"'"
948 <<
" Falling back to optimizing all dependences.\n";
974 Proximity = keepBoundedDistances(Proximity, ExactProximity);
977 <<
"warning: Option -polly-opt-simplify-deps should either be 'yes' "
978 "or 'no'. Falling back to default: 'yes'\n";
981 POLLY_DEBUG(dbgs() <<
"\n\nCompute schedule from: ");
983 POLLY_DEBUG(dbgs() <<
"Proximity := " << Proximity <<
";\n");
984 POLLY_DEBUG(dbgs() <<
"Validity := " << Validity <<
";\n");
986 int IslMaximizeBands;
988 IslMaximizeBands = 1;
990 IslMaximizeBands = 0;
993 <<
"warning: Option -polly-opt-maximize-bands should either be 'yes'"
994 " or 'no'. Falling back to default: 'yes'\n";
995 IslMaximizeBands = 1;
998 int IslOuterCoincidence;
1000 IslOuterCoincidence = 1;
1002 IslOuterCoincidence = 0;
1004 errs() <<
"warning: Option -polly-opt-outer-coincidence should either be "
1005 "'yes' or 'no'. Falling back to default: 'no'\n";
1006 IslOuterCoincidence = 0;
1019 SC = SC.set_proximity(Proximity);
1020 SC = SC.set_validity(Validity);
1021 SC = SC.set_coincidence(Validity);
1025 Schedule = SC.compute_schedule();
1032 POLLY_DEBUG(printSchedule(dbgs(), Schedule,
"After rescheduling"));
1035 walkScheduleTreeForStatistics(Schedule, 1);
1045 const OptimizerAdditionalInfoTy OAI = {
1053 if (!Schedule.
is_null() && (OAI.PatternOpts || OAI.Postopts || OAI.Prevect)) {
1054 Schedule = ScheduleTreeOptimizer::optimizeSchedule(Schedule, &OAI);
1056 POLLY_DEBUG(printSchedule(dbgs(), Schedule,
"After post-optimizations"));
1057 walkScheduleTreeForStatistics(Schedule, 2);
1061 if (MaxOpGuard.hasQuotaExceeded()) {
1062 POLLY_DEBUG(dbgs() <<
"Schedule optimizer calculation exceeds ISL quota\n");
1069 dbgs() <<
"ISL reported an error during the computation of a new "
1071 << File <<
":" << Line <<
": " << Msg;
1075 }
else if (Schedule.
is_null()) {
1076 POLLY_DEBUG(dbgs() <<
"Schedule optimizer did not compute a new schedule "
1077 "for unknown reasons\n");
1082 if (!HasUserTransformation &&
1083 !ScheduleTreeOptimizer::isProfitableSchedule(
S, Schedule))
1086 auto ScopStats =
S.getStatistics();
1088 NumAffineLoopsOptimized += ScopStats.NumAffineLoops;
1089 NumBoxedLoopsOptimized += ScopStats.NumBoxedLoops;
1090 LastSchedule = Schedule;
1092 S.setScheduleTree(Schedule);
1093 S.markAsOptimized();
1099static void runScheduleOptimizerPrinter(raw_ostream &OS,
1104 OS <<
"Calculated schedule:\n";
1117 OS << ScheduleStr <<
"\n";
1129 OptimizationRemarkEmitter ORE(&
S.getFunction());
1131 bool DepsChanged =
false;
1132 runIslScheduleOptimizerImpl(
S, GetDeps, TTI, &ORE, LastSchedule, DepsChanged);
1138 <<
"Printing analysis 'Polly - Optimize schedule of SCoP' for region: '"
1139 <<
S.getName() <<
"' in function '" <<
S.getFunction().getName()
1141 runScheduleOptimizerPrinter(outs(), LastSchedule);
llvm::cl::OptionCategory PollyCategory
static cl::opt< bool > IsolateCompleteTiles2ndLevel("polly-isolate-complete-tiles-2nd-level", cl::desc("Separate the complete tiles of the second level of tiling from " "the partial ones"), cl::Hidden, cl::init(false), cl::cat(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< bool > IsolateCompleteTiles("polly-isolate-complete-tiles", cl::desc("Separate the complete tiles of a tiled band from the partial " "ones, so that the point loops of the complete tiles have " "constant bounds"), cl::Hidden, cl::init(false), 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 > IsolateCompleteRegisterTiles("polly-isolate-complete-register-tiles", cl::desc("Separate the complete register tiles from the partial ones, so " "that their unrolled point loops need no guards"), cl::Hidden, cl::init(false), 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::opt< int > IsolateCompleteTileDims("polly-isolate-complete-tile-dims", cl::desc("Number of innermost tile dimensions that have to be complete for " "a tile to be isolated (0: all of them). Requiring fewer of them " "generates less code, but also gives fewer point loops a constant " "bound"), cl::Hidden, cl::init(0), cl::cat(PollyCategory))
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.
llvm::iota_range< unsigned > rangeIslSize(unsigned Begin, isl::size End)
Check that End is valid and return an iterator from Begin to End.
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::set getCompleteTilePrefixes(isl::set ScheduleRange, llvm::ArrayRef< int > TileSizes, unsigned NumCompleteDims)
Compute the prefixes of the complete tiles of a tiled band.
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")