57#include "llvm/ADT/Sequence.h"
58#include "llvm/ADT/Statistic.h"
59#include "llvm/Analysis/OptimizationRemarkEmitter.h"
60#include "llvm/InitializePasses.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. "),
104 cl::Hidden, cl::init(300000), cl::ZeroOrMore,
109 cl::desc(
"Aggressively try to fuse everything"), cl::Hidden,
113 "polly-opt-outer-coincidence",
114 cl::desc(
"Try to construct schedules where the outer member of each band "
115 "satisfies the coincidence constraints (yes/no)"),
119 "polly-prevect-width",
121 "The number of loop iterations to strip-mine for pre-vectorization"),
125 cl::desc(
"Enable loop tiling"),
129 "polly-default-tile-size",
130 cl::desc(
"The default tile size (if not enough were provided by"
131 " --polly-tile-sizes)"),
136 cl::desc(
"A tile size for each loop dimension, filled "
137 "with --polly-default-tile-size"),
142 cl::desc(
"Enable a 2nd level loop of loop tiling"),
146 "polly-2nd-level-default-tile-size",
147 cl::desc(
"The default 2nd-level tile size (if not enough were provided by"
148 " --polly-2nd-level-tile-sizes)"),
153 cl::desc(
"A tile size for each loop dimension, filled "
154 "with --polly-default-tile-size"),
155 cl::Hidden, cl::CommaSeparated,
159 cl::desc(
"Enable register tiling"),
163 "polly-register-tiling-default-tile-size",
164 cl::desc(
"The default register tile size (if not enough were provided by"
165 " --polly-register-tile-sizes)"),
170 cl::desc(
"A tile size for each loop dimension, filled "
171 "with --polly-register-tile-size"),
175 "polly-pragma-based-opts",
176 cl::desc(
"Apply user-directed transformation from metadata"),
180 cl::desc(
"Optimize SCoPs using ISL"),
185 cl::desc(
"Perform optimizations based on pattern matching"),
190 cl::desc(
"Apply post-rescheduling optimizations such as "
191 "tiling (requires -polly-reschedule)"),
195 "polly-optimized-scops",
196 cl::desc(
"Polly - Dump polyhedral description of Scops optimized with "
197 "the isl scheduling optimizer and the set of post-scheduling "
198 "transformations is applied on the schedule tree"),
202STATISTIC(ScopsRescheduled,
"Number of scops rescheduled");
205STATISTIC(NumAffineLoopsOptimized,
"Number of affine loops optimized");
206STATISTIC(NumBoxedLoopsOptimized,
"Number of boxed loops optimized");
208#define THREE_STATISTICS(VARNAME, DESC) \
209 static Statistic VARNAME[3] = { \
210 {DEBUG_TYPE, #VARNAME "0", DESC " (original)"}, \
211 {DEBUG_TYPE, #VARNAME "1", DESC " (after scheduler)"}, \
212 {DEBUG_TYPE, #VARNAME "2", DESC " (after optimizer)"}}
221STATISTIC(FirstLevelTileOpts,
"Number of first level tiling applied");
222STATISTIC(SecondLevelTileOpts,
"Number of second level tiling applied");
223STATISTIC(RegisterTileOpts,
"Number of register tiling applied");
224STATISTIC(PrevectOpts,
"Number of strip-mining for prevectorization applied");
226 "Number of matrix multiplication patterns detected and optimized");
233struct OptimizerAdditionalInfoTy {
234 const llvm::TargetTransformInfo *TTI;
242class ScheduleTreeOptimizer final {
260 const OptimizerAdditionalInfoTy *OAI =
nullptr);
277 const OptimizerAdditionalInfoTy *OAI =
nullptr);
349 unsigned DimToVectorize,
388 isl::set ScheduleRange{ScheduleRangeUSet};
418 assert(DimToVectorize < ScheduleDimensions);
420 if (DimToVectorize > 0) {
423 Node = Node.
child(0);
425 if (DimToVectorize < ScheduleDimensions - 1)
429 Sizes = Sizes.set_val(0,
isl::val(Node.
ctx(), VectorWidth));
432 Node = isolateFullPartialTiles(Node, VectorWidth);
433 Node = Node.
child(0);
444 InsertSimdMarkers SimdMarkerInserter;
445 Node = SimdMarkerInserter.visit(Node);
463 auto Sequence = Node.
child(0);
467 auto Child = Sequence.
child(c);
491 if (!isOneTimeParentBandNode(Node))
502 return isSimpleInnermostBand(Node);
506 if (!isOneTimeParentBandNode(Node))
517 FirstLevelTileOpts++;
523 SecondLevelTileOpts++;
540 for (
int i = Dims - 1; i >= 0; i--)
552 const OptimizerAdditionalInfoTy *OAI =
553 static_cast<const OptimizerAdditionalInfoTy *
>(User);
554 assert(OAI &&
"Expecting optimization options");
558 if (OAI->PatternOpts && isPMOptimizableBandNode(Node)) {
561 if (!PatternOptimizedSchedule.
is_null()) {
563 OAI->DepsChanged =
true;
564 return PatternOptimizedSchedule.
release();
568 if (!isTileableBandNode(Node))
572 Node = applyTileBandOpt(Node);
577 Node = applyPrevectBandOpt(Node);
584ScheduleTreeOptimizer::optimizeSchedule(
isl::schedule Schedule,
585 const OptimizerAdditionalInfoTy *OAI) {
587 Root = optimizeScheduleNode(Root, OAI);
588 return Root.get_schedule();
595 const_cast<void *
>(
static_cast<const void *
>(OAI))));
599bool ScheduleTreeOptimizer::isProfitableSchedule(
Scop &
S,
613 auto NewScheduleMap = NewSchedule.
get_map();
614 auto OldSchedule =
S.getSchedule();
615 assert(!OldSchedule.is_null() &&
616 "Only IslScheduleOptimizer can insert extension nodes "
617 "that make Scop::getSchedule() return nullptr.");
618 bool changed = !OldSchedule.is_equal(NewScheduleMap);
622class IslScheduleOptimizerWrapperPass final :
public ScopPass {
626 explicit IslScheduleOptimizerWrapperPass() :
ScopPass(ID) {}
629 bool runOnScop(
Scop &
S)
override;
632 void printScop(raw_ostream &OS,
Scop &
S)
const override;
635 void getAnalysisUsage(AnalysisUsage &AU)
const override;
638 void releaseMemory()
override {
644 std::shared_ptr<isl_ctx> IslCtx;
648char IslScheduleOptimizerWrapperPass::ID = 0;
651static void printSchedule(llvm::raw_ostream &OS,
const isl::schedule &Schedule,
658 OS << Desc <<
": \n" <<
Str <<
"\n";
673static void walkScheduleTreeForStatistics(
isl::schedule Schedule,
int Version) {
681 isl::schedule_node Node = isl::manage_copy(nodeptr);
682 int Version = *static_cast<int *>(user);
684 switch (isl_schedule_node_get_type(Node.get())) {
685 case isl_schedule_node_band: {
687 if (isl_schedule_node_band_get_permutable(Node.get()) ==
689 NumPermutable[Version]++;
691 int CountMembers = isl_schedule_node_band_n_member(Node.get());
692 NumBandMembers[Version] += CountMembers;
693 for (int i = 0; i < CountMembers; i += 1) {
694 if (Node.as<isl::schedule_node_band>().member_get_coincident(i))
695 NumCoincident[Version]++;
700 case isl_schedule_node_filter:
701 NumFilters[Version]++;
704 case isl_schedule_node_extension:
705 NumExtension[Version]++;
717static void runIslScheduleOptimizer(
720 TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE,
724 if (
S.getSize() == 0) {
733 walkScheduleTreeForStatistics(
S.getScheduleTree(), 0);
734 POLLY_DEBUG(printSchedule(dbgs(), Schedule,
"Original schedule tree"));
736 bool HasUserTransformation =
false;
740 if (ManuallyTransformed.
is_null()) {
741 POLLY_DEBUG(dbgs() <<
"Error during manual optimization\n");
745 if (ManuallyTransformed.
get() != Schedule.
get()) {
747 HasUserTransformation =
true;
748 Schedule = std::move(ManuallyTransformed);
750 printSchedule(dbgs(), Schedule,
"After manual transformations"));
758 if (!HasUserTransformation &&
S.hasDisableHeuristicsHint()) {
759 POLLY_DEBUG(dbgs() <<
"Heuristic optimizations disabled by metadata\n");
766 POLLY_DEBUG(dbgs() <<
"DependenceInfo for another SCoP/isl_ctx\n");
770 POLLY_DEBUG(dbgs() <<
"Dependency information not available\n");
780 POLLY_DEBUG(dbgs() <<
"Skipping rescheduling due to command line option\n");
781 }
else if (HasUserTransformation) {
783 dbgs() <<
"Skipping rescheduling due to manual transformation\n");
796 errs() <<
"Do not know how to optimize for '" <<
OptimizeDeps <<
"'"
797 <<
" Falling back to optimizing all dependences.\n";
824 <<
"warning: Option -polly-opt-simplify-deps should either be 'yes' "
825 "or 'no'. Falling back to default: 'yes'\n";
828 POLLY_DEBUG(dbgs() <<
"\n\nCompute schedule from: ");
830 POLLY_DEBUG(dbgs() <<
"Proximity := " << Proximity <<
";\n");
831 POLLY_DEBUG(dbgs() <<
"Validity := " << Validity <<
";\n");
833 int IslMaximizeBands;
835 IslMaximizeBands = 1;
837 IslMaximizeBands = 0;
840 <<
"warning: Option -polly-opt-maximize-bands should either be 'yes'"
841 " or 'no'. Falling back to default: 'yes'\n";
842 IslMaximizeBands = 1;
845 int IslOuterCoincidence;
847 IslOuterCoincidence = 1;
849 IslOuterCoincidence = 0;
851 errs() <<
"warning: Option -polly-opt-outer-coincidence should either be "
852 "'yes' or 'no'. Falling back to default: 'no'\n";
853 IslOuterCoincidence = 0;
868 SC = SC.set_proximity(Proximity);
869 SC = SC.set_validity(Validity);
870 SC = SC.set_coincidence(Validity);
874 Schedule = SC.compute_schedule();
876 if (MaxOpGuard.hasQuotaExceeded())
878 dbgs() <<
"Schedule optimizer calculation exceeds ISL quota\n");
884 POLLY_DEBUG(printSchedule(dbgs(), Schedule,
"After rescheduling"));
887 walkScheduleTreeForStatistics(Schedule, 1);
902 const OptimizerAdditionalInfoTy OAI = {
909 if (OAI.PatternOpts || OAI.Postopts || OAI.Prevect) {
910 Schedule = ScheduleTreeOptimizer::optimizeSchedule(Schedule, &OAI);
912 POLLY_DEBUG(printSchedule(dbgs(), Schedule,
"After post-optimizations"));
913 walkScheduleTreeForStatistics(Schedule, 2);
917 if (!HasUserTransformation &&
918 !ScheduleTreeOptimizer::isProfitableSchedule(
S, Schedule))
921 auto ScopStats =
S.getStatistics();
923 NumAffineLoopsOptimized += ScopStats.NumAffineLoops;
924 NumBoxedLoopsOptimized += ScopStats.NumBoxedLoops;
925 LastSchedule = Schedule;
927 S.setScheduleTree(Schedule);
934bool IslScheduleOptimizerWrapperPass::runOnScop(
Scop &
S) {
938 IslCtx =
S.getSharedIslCtx();
940 auto getDependences =
945 OptimizationRemarkEmitter &ORE =
946 getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
947 TargetTransformInfo *TTI =
948 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
950 bool DepsChanged =
false;
951 runIslScheduleOptimizer(
S, getDependences, TTI, &ORE, LastSchedule,
954 getAnalysis<DependenceInfo>().abandonDependences();
958static void runScheduleOptimizerPrinter(raw_ostream &OS,
963 OS <<
"Calculated schedule:\n";
976 OS << ScheduleStr <<
"\n";
981void IslScheduleOptimizerWrapperPass::printScop(raw_ostream &OS,
Scop &)
const {
982 runScheduleOptimizerPrinter(OS, LastSchedule);
985void IslScheduleOptimizerWrapperPass::getAnalysisUsage(
986 AnalysisUsage &AU)
const {
989 AU.addRequired<TargetTransformInfoWrapperPass>();
990 AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
993 AU.addPreserved<OptimizationRemarkEmitterWrapperPass>();
999 return new IslScheduleOptimizerWrapperPass();
1003 "Polly - Optimize schedule of SCoP",
false,
false);
1009 "Polly - Optimize schedule of SCoP",
false,
false)
1011static
llvm::PreservedAnalyses
1019 OptimizationRemarkEmitter ORE(&
S.getFunction());
1020 TargetTransformInfo *TTI = &SAR.TTI;
1022 bool DepsChanged =
false;
1023 runIslScheduleOptimizer(
S, GetDeps, TTI, &ORE, LastSchedule, DepsChanged);
1028 *OS <<
"Printing analysis 'Polly - Optimize schedule of SCoP' for region: '"
1029 <<
S.getName() <<
"' in function '" <<
S.getFunction().getName()
1031 runScheduleOptimizerPrinter(*OS, LastSchedule);
1033 return PreservedAnalyses::all();
1036llvm::PreservedAnalyses
1039 return runIslScheduleOptimizerUsingNPM(
S, SAM, SAR, U,
nullptr);
1042llvm::PreservedAnalyses
1046 return runIslScheduleOptimizerUsingNPM(
S, SAM, SAR, U, &
OS);
1053class IslScheduleOptimizerPrinterLegacyPass final :
public ScopPass {
1057 IslScheduleOptimizerPrinterLegacyPass()
1058 : IslScheduleOptimizerPrinterLegacyPass(outs()) {}
1059 explicit IslScheduleOptimizerPrinterLegacyPass(llvm::raw_ostream &OS)
1062 bool runOnScop(
Scop &
S)
override {
1063 IslScheduleOptimizerWrapperPass &P =
1064 getAnalysis<IslScheduleOptimizerWrapperPass>();
1066 OS <<
"Printing analysis '" << P.getPassName() <<
"' for region: '"
1067 <<
S.getRegion().getNameStr() <<
"' in function '"
1068 <<
S.getFunction().getName() <<
"':\n";
1074 void getAnalysisUsage(AnalysisUsage &AU)
const override {
1076 AU.addRequired<IslScheduleOptimizerWrapperPass>();
1077 AU.setPreservesAll();
1081 llvm::raw_ostream &OS;
1084char IslScheduleOptimizerPrinterLegacyPass::ID = 0;
1088 return new IslScheduleOptimizerPrinterLegacyPass(OS);
1092 "polly-print-opt-isl",
1093 "Polly - Print optimizer schedule of SCoP",
false,
false);
1096 "polly-print-opt-isl",
1097 "Polly - Print optimizer schedule of SCoP",
false,
false)
INITIALIZE_PASS_BEGIN(DependenceInfo, "polly-dependences", "Polly - Calculate dependences", false, false)
INITIALIZE_PASS_END(DependenceInfo, "polly-dependences", "Polly - Calculate dependences", false, false) namespace
INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass)
polly dump Polly Dump Function
polly dump Polly Dump Module
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))
INITIALIZE_PASS_END(IslScheduleOptimizerWrapperPass, "polly-opt-isl", "Polly - Optimize schedule of SCoP", false, false) static llvm
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))
INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
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 > 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< int > ScheduleComputeOut("polly-schedule-computeout", cl::desc("Bound the scheduler by maximal amount" "of computational steps. "), cl::Hidden, cl::init(300000), cl::ZeroOrMore, 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))
INITIALIZE_PASS_BEGIN(IslScheduleOptimizerWrapperPass, "polly-opt-isl", "Polly - Optimize schedule of SCoP", false, false)
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))
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)
boolean member_get_coincident(int pos) const
isl::schedule_node insert_mark(isl::id mark) const
isl::schedule_node child(int pos) const
__isl_give isl_schedule_node * release()
isl::union_map get_prefix_schedule_relation() const
isl::schedule_node parent() const
isl::schedule_node first_child() const
__isl_keep isl_schedule_node * get() const
__isl_keep isl_schedule * get() const
isl::schedule_node get_root() const
isl::union_map get_map() const
isl::union_set range() const
isl::union_map gist_domain(isl::union_set uset) const
isl::union_map gist_range(isl::union_set uset) const
isl::union_set unite(isl::union_set uset2) const
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.
The legacy pass manager's analysis pass to compute scop information for a region.
ScopPass - This class adapts the RegionPass interface to allow convenient creation of passes that ope...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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)
This file contains the declaration of the PolyhedralInfo class, which will provide an interface to ex...
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::Pass * createIslScheduleOptimizerWrapperPass()
isl::schedule_node tryOptimizeMatMulPattern(isl::schedule_node Node, const llvm::TargetTransformInfo *TTI, const Dependences *D)
Apply the BLIS matmul optimization pattern if possible.
llvm::Pass * createIslScheduleOptimizerPrinterLegacyPass(llvm::raw_ostream &OS)
isl::union_set getIsolateOptions(isl::set IsolateDomain, unsigned OutDimsNum)
Create an isl::union_set, which describes the isolate option based on IsolateDomain.
AnalysisManager< Scop, ScopStandardAnalysisResults & > ScopAnalysisManager
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)
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)
@ 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.
llvm::PreservedAnalyses run(Scop &S, ScopAnalysisManager &SAM, ScopStandardAnalysisResults &SAR, SPMUpdater &U)
PreservedAnalyses run(Scop &S, ScopAnalysisManager &, ScopStandardAnalysisResults &SAR, SPMUpdater &)
Recursively visit all nodes of a schedule tree while allowing changes.
static TupleKindPtr Domain("Domain")