@@ -237,6 +237,7 @@ struct OptimizerAdditionalInfoTy {
237237 bool Postopts;
238238 bool Prevect;
239239 bool &DepsChanged;
240+ IslMaxOperationsGuard &MaxOpGuard;
240241};
241242
242243class ScheduleTreeOptimizer final {
@@ -381,6 +382,8 @@ class ScheduleTreeOptimizer final {
381382isl::schedule_node
382383ScheduleTreeOptimizer::isolateFullPartialTiles (isl::schedule_node Node,
383384 int VectorWidth) {
385+ if (Node.is_null ())
386+ return {};
384387 assert (isl_schedule_node_get_type (Node.get ()) == isl_schedule_node_band);
385388 Node = Node.child (0 ).child (0 );
386389 isl::union_map SchedRelUMap = Node.get_prefix_schedule_relation ();
@@ -391,6 +394,8 @@ ScheduleTreeOptimizer::isolateFullPartialTiles(isl::schedule_node Node,
391394 isl::union_set IsolateOption = getIsolateOptions (IsolateDomain, 1 );
392395 Node = Node.parent ().parent ();
393396 isl::union_set Options = IsolateOption.unite (AtomicOption);
397+ if (Node.is_null ())
398+ return {};
394399 isl::schedule_node_band Result =
395400 Node.as <isl::schedule_node_band>().set_ast_build_options (Options);
396401 return Result;
@@ -411,9 +416,13 @@ struct InsertSimdMarkers final : ScheduleNodeRewriter<InsertSimdMarkers> {
411416
412417isl::schedule_node ScheduleTreeOptimizer::prevectSchedBand (
413418 isl::schedule_node Node, unsigned DimToVectorize, int VectorWidth) {
419+ if (Node.is_null ())
420+ return {};
414421 assert (isl_schedule_node_get_type (Node.get ()) == isl_schedule_node_band);
415422
416423 auto Space = isl::manage (isl_schedule_node_band_get_space (Node.get ()));
424+ if (Space.is_null ())
425+ return {};
417426 unsigned ScheduleDimensions = unsignedFromIslSize (Space.dim (isl::dim::set));
418427 assert (DimToVectorize < ScheduleDimensions);
419428
@@ -439,12 +448,15 @@ isl::schedule_node ScheduleTreeOptimizer::prevectSchedBand(
439448 // Sink the inner loop into the smallest possible statements to make them
440449 // represent a single vector instruction if possible.
441450 Node = isl::manage (isl_schedule_node_band_sink (Node.release ()));
451+ if (Node.is_null ())
452+ return {};
442453
443454 // Add SIMD markers to those vector statements.
444455 InsertSimdMarkers SimdMarkerInserter;
445456 Node = SimdMarkerInserter.visit (Node);
446457
447- PrevectOpts++;
458+ if (!Node.is_null ())
459+ PrevectOpts++;
448460 return Node.parent ();
449461}
450462
@@ -535,6 +547,8 @@ ScheduleTreeOptimizer::applyTileBandOpt(isl::schedule_node Node) {
535547isl::schedule_node
536548ScheduleTreeOptimizer::applyPrevectBandOpt (isl::schedule_node Node) {
537549 auto Space = isl::manage (isl_schedule_node_band_get_space (Node.get ()));
550+ if (Space.is_null ())
551+ return {};
538552 int Dims = unsignedFromIslSize (Space.dim (isl::dim::set));
539553
540554 for (int i = Dims - 1 ; i >= 0 ; i--)
@@ -572,9 +586,14 @@ ScheduleTreeOptimizer::optimizeBand(__isl_take isl_schedule_node *NodeArg,
572586 Node = applyTileBandOpt (Node);
573587
574588 if (OAI->Prevect ) {
589+ IslQuotaScope MaxScope = OAI->MaxOpGuard .enter ();
590+
575591 // FIXME: Prevectorization requirements are different from those checked by
576592 // isTileableBandNode.
577593 Node = applyPrevectBandOpt (Node);
594+
595+ if (OAI->MaxOpGuard .hasQuotaExceeded () || Node.is_null ())
596+ return (isl::schedule_node ()).release ();
578597 }
579598
580599 return Node.release ();
@@ -771,6 +790,10 @@ static void runIslScheduleOptimizer(
771790 return ;
772791 }
773792
793+ isl_ctx *Ctx = S.getIslCtx ().get ();
794+ IslMaxOperationsGuard MaxOpGuard (Ctx, ScheduleComputeOut,
795+ /* AutoEnter=*/ false );
796+
774797 // Apply ISL's algorithm only if not overridden by the user. Note that
775798 // post-rescheduling optimizations (tiling, pattern-based, prevectorization)
776799 // rely on the coincidence/permutable annotations on schedule tree bands that
@@ -853,8 +876,6 @@ static void runIslScheduleOptimizer(
853876 IslOuterCoincidence = 0 ;
854877 }
855878
856- isl_ctx *Ctx = S.getIslCtx ().get ();
857-
858879 isl_options_set_schedule_outer_coincidence (Ctx, IslOuterCoincidence);
859880 isl_options_set_schedule_maximize_band_depth (Ctx, IslMaximizeBands);
860881 isl_options_set_schedule_max_constant_term (Ctx, MaxConstantTerm);
@@ -870,28 +891,20 @@ static void runIslScheduleOptimizer(
870891 SC = SC.set_coincidence (Validity);
871892
872893 {
873- IslMaxOperationsGuard MaxOpGuard (Ctx, ScheduleComputeOut );
894+ IslQuotaScope MaxOpScope = MaxOpGuard. enter ( );
874895 Schedule = SC.compute_schedule ();
875-
876- if (MaxOpGuard.hasQuotaExceeded ())
877- POLLY_DEBUG (
878- dbgs () << " Schedule optimizer calculation exceeds ISL quota\n " );
879896 }
880897
881898 isl_options_set_on_error (Ctx, OnErrorStatus);
882899
883- ScopsRescheduled++;
900+ if (!Schedule.is_null ())
901+ ScopsRescheduled++;
884902 POLLY_DEBUG (printSchedule (dbgs (), Schedule, " After rescheduling" ));
885903 }
886904
887905 walkScheduleTreeForStatistics (Schedule, 1 );
888906
889- // In cases the scheduler is not able to optimize the code, we just do not
890- // touch the schedule.
891- if (Schedule.is_null ())
892- return ;
893-
894- if (GreedyFusion) {
907+ if (GreedyFusion && !Schedule.is_null ()) {
895908 isl::union_map Validity = D.getDependences (
896909 Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW);
897910 Schedule = applyGreedyFusion (Schedule, Validity);
@@ -905,14 +918,20 @@ static void runIslScheduleOptimizer(
905918 /* PatternOpts=*/ !HasUserTransformation && PMBasedOpts,
906919 /* Postopts=*/ !HasUserTransformation && EnablePostopts,
907920 /* Prevect=*/ PollyVectorizerChoice != VECTORIZER_NONE,
908- DepsChanged};
909- if (OAI.PatternOpts || OAI.Postopts || OAI.Prevect ) {
921+ DepsChanged,
922+ MaxOpGuard};
923+ if (!Schedule.is_null () && (OAI.PatternOpts || OAI.Postopts || OAI.Prevect )) {
910924 Schedule = ScheduleTreeOptimizer::optimizeSchedule (Schedule, &OAI);
911925 Schedule = hoistExtensionNodes (Schedule);
912926 POLLY_DEBUG (printSchedule (dbgs (), Schedule, " After post-optimizations" ));
913927 walkScheduleTreeForStatistics (Schedule, 2 );
914928 }
915929
930+ if (MaxOpGuard.hasQuotaExceeded ()) {
931+ POLLY_DEBUG (dbgs () << " Schedule optimizer calculation exceeds ISL quota\n " );
932+ return ;
933+ }
934+
916935 // Skip profitability check if user transformation(s) have been applied.
917936 if (!HasUserTransformation &&
918937 !ScheduleTreeOptimizer::isProfitableSchedule (S, Schedule))
0 commit comments