[clang] [polly] [llvm] [polly][ScheduleOptimizer] Fix long compile time(hang) reported in polly (PR #75141)

Karthika Devi C via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 19 00:03:15 PST 2023


https://github.com/kartcq updated https://github.com/llvm/llvm-project/pull/75141

>From 98745d850c588eaf9b5d2ac6f71c79873107501f Mon Sep 17 00:00:00 2001
From: kartcq <quic_kartc at quicinc.com>
Date: Mon, 11 Dec 2023 05:22:33 -0800
Subject: [PATCH 1/4] [polly][ScheduleOptimizer] Bail out on exceeding Schedule
 compute's ISL  quota

There is no upper cap set on current Schedule Optimizer to compute schedule. In
some cases a very long compile time taken to compute the schedule resulting in
hang kind of behavior. This patch introduces a flag 'polly-schedule-computeout'
to pass the cap which is initialized to 300000. This patch handles the compute
out cases by bailing out and exiting gracefully.

Change-Id: Id506832df4ae8d3f140579ba10cf570e18efac62
---
 polly/lib/Transform/ScheduleOptimizer.cpp     | 25 +++++
 .../ScheduleOptimizer/schedule_computeout.ll  | 97 +++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 polly/test/ScheduleOptimizer/schedule_computeout.ll

diff --git a/polly/lib/Transform/ScheduleOptimizer.cpp b/polly/lib/Transform/ScheduleOptimizer.cpp
index 35a0a4def0403d..8ee2b66339adbc 100644
--- a/polly/lib/Transform/ScheduleOptimizer.cpp
+++ b/polly/lib/Transform/ScheduleOptimizer.cpp
@@ -96,6 +96,13 @@ static cl::opt<std::string>
                       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::ZeroOrMore,
+                       cl::cat(PollyCategory));
+
 static cl::opt<bool>
     GreedyFusion("polly-loopfusion-greedy",
                  cl::desc("Aggressively try to fuse everything"), cl::Hidden,
@@ -860,7 +867,25 @@ static void runIslScheduleOptimizer(
     SC = SC.set_proximity(Proximity);
     SC = SC.set_validity(Validity);
     SC = SC.set_coincidence(Validity);
+
+    // Save error handling behavior
+    long MaxOperations = isl_ctx_get_max_operations(Ctx);
+    isl_ctx_set_max_operations(Ctx, ScheduleComputeOut);
     Schedule = SC.compute_schedule();
+    bool ScheduleQuota = false;
+    if (isl_ctx_last_error(Ctx) == isl_error_quota) {
+      isl_ctx_reset_error(Ctx);
+      LLVM_DEBUG(
+          dbgs() << "Schedule optimizer calculation exceeds ISL quota\n");
+      ScheduleQuota = true;
+    }
+    isl_options_set_on_error(Ctx, ISL_ON_ERROR_ABORT);
+    isl_ctx_reset_operations(Ctx);
+    isl_ctx_set_max_operations(Ctx, MaxOperations);
+
+    if (ScheduleQuota)
+      return;
+
     isl_options_set_on_error(Ctx, OnErrorStatus);
 
     ScopsRescheduled++;
diff --git a/polly/test/ScheduleOptimizer/schedule_computeout.ll b/polly/test/ScheduleOptimizer/schedule_computeout.ll
new file mode 100644
index 00000000000000..3e768e02c8a740
--- /dev/null
+++ b/polly/test/ScheduleOptimizer/schedule_computeout.ll
@@ -0,0 +1,97 @@
+; RUN: opt -S -polly-optree -polly-delicm  -polly-opt-isl -polly-schedule-computeout=100000 -debug-only="polly-opt-isl" < %s 2>&1 | FileCheck %s
+; Bailout if the computations of schedule compute exceeds the max scheduling quota.
+; Max compute out is initialized to 300000, Here it is set to 100000 for test purpose.
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-gnu"
+
+ at a = dso_local local_unnamed_addr global ptr null, align 8
+ at b = dso_local local_unnamed_addr global ptr null, align 8
+ at c = dso_local local_unnamed_addr global ptr null, align 8
+
+define dso_local void @foo(i32 noundef %I, i32 noundef %J, i32 noundef %K1, i32 noundef %K2, i32 noundef %L1, i32 noundef %L2) local_unnamed_addr {
+entry:
+  %j = alloca i32, align 4
+  store volatile i32 0, ptr %j, align 4
+  %j.0.j.0.j.0.54 = load volatile i32, ptr %j, align 4
+  %cmp55 = icmp slt i32 %j.0.j.0.j.0.54, %J
+  br i1 %cmp55, label %for.body.lr.ph, label %for.cond.cleanup
+
+for.body.lr.ph:                                   ; preds = %entry
+  %0 = load ptr, ptr @a, align 8
+  %1 = load ptr, ptr @b, align 8
+  %2 = load ptr, ptr %1, align 8
+  %cmp352 = icmp slt i32 %L1, %L2
+  %cmp750 = icmp slt i32 %K1, %K2
+  %3 = sext i32 %K1 to i64
+  %4 = sext i32 %L1 to i64
+  br label %for.body
+
+for.cond.cleanup:                                 ; preds = %for.cond.cleanup4, %entry
+  ret void
+
+for.body:                                         ; preds = %for.cond.cleanup4, %for.body.lr.ph
+  br i1 %cmp352, label %for.cond6.preheader.preheader, label %for.cond.cleanup4
+
+for.cond6.preheader.preheader:                    ; preds = %for.body
+  %wide.trip.count66 = sext i32 %L2 to i64
+  br label %for.cond6.preheader
+
+for.cond6.preheader:                              ; preds = %for.cond.cleanup8, %for.cond6.preheader.preheader
+  %indvars.iv61 = phi i64 [ %4, %for.cond6.preheader.preheader ], [ %indvars.iv.next62, %for.cond.cleanup8 ]
+  br i1 %cmp750, label %for.cond10.preheader.lr.ph, label %for.cond.cleanup8
+
+for.cond10.preheader.lr.ph:                       ; preds = %for.cond6.preheader
+  %5 = mul nsw i64 %indvars.iv61, 516
+  %6 = mul nsw i64 %indvars.iv61, 516
+  %wide.trip.count = sext i32 %K2 to i64
+  br label %for.cond10.preheader
+
+for.cond.cleanup4:                                ; preds = %for.cond.cleanup8, %for.body
+  %j.0.j.0.j.0.45 = load volatile i32, ptr %j, align 4
+  %inc34 = add nsw i32 %j.0.j.0.j.0.45, 1
+  store volatile i32 %inc34, ptr %j, align 4
+  %j.0.j.0.j.0. = load volatile i32, ptr %j, align 4
+  %cmp = icmp slt i32 %j.0.j.0.j.0., %J
+  br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond10.preheader:                             ; preds = %for.cond.cleanup12, %for.cond10.preheader.lr.ph
+  %indvars.iv = phi i64 [ %3, %for.cond10.preheader.lr.ph ], [ %indvars.iv.next, %for.cond.cleanup12 ]
+  %7 = getelementptr float, ptr %0, i64 %indvars.iv
+  %arrayidx18 = getelementptr float, ptr %7, i64 %5
+  %8 = load float, ptr %arrayidx18, align 4
+  br label %for.cond14.preheader
+
+for.cond.cleanup8:                                ; preds = %for.cond.cleanup12, %for.cond6.preheader
+  %indvars.iv.next62 = add nsw i64 %indvars.iv61, 1
+  %exitcond67.not = icmp eq i64 %indvars.iv.next62, %wide.trip.count66
+  br i1 %exitcond67.not, label %for.cond.cleanup4, label %for.cond6.preheader
+
+for.cond14.preheader:                             ; preds = %for.cond.cleanup16, %for.cond10.preheader
+  %m.049 = phi i32 [ -2, %for.cond10.preheader ], [ %inc21, %for.cond.cleanup16 ]
+  %sum.048 = phi float [ 0.000000e+00, %for.cond10.preheader ], [ %add19, %for.cond.cleanup16 ]
+  br label %for.body17
+
+for.cond.cleanup12:                               ; preds = %for.cond.cleanup16
+  %9 = getelementptr float, ptr %2, i64 %indvars.iv
+  %arrayidx26 = getelementptr float, ptr %9, i64 %6
+  store float %add19, ptr %arrayidx26, align 4
+  %indvars.iv.next = add nsw i64 %indvars.iv, 1
+  %exitcond60.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
+  br i1 %exitcond60.not, label %for.cond.cleanup8, label %for.cond10.preheader
+
+for.cond.cleanup16:                               ; preds = %for.body17
+  %inc21 = add nsw i32 %m.049, 1
+  %exitcond56.not = icmp eq i32 %inc21, 3
+  br i1 %exitcond56.not, label %for.cond.cleanup12, label %for.cond14.preheader
+
+for.body17:                                       ; preds = %for.body17, %for.cond14.preheader
+  %n.047 = phi i32 [ -2, %for.cond14.preheader ], [ %inc, %for.body17 ]
+  %sum.146 = phi float [ %sum.048, %for.cond14.preheader ], [ %add19, %for.body17 ]
+  %add19 = fadd float %sum.146, %8
+  %inc = add nsw i32 %n.047, 1
+  %exitcond.not = icmp eq i32 %inc, 3
+  br i1 %exitcond.not, label %for.cond.cleanup16, label %for.body17
+}
+
+; CHECK: Schedule optimizer calculation exceeds ISL quota

>From c1d5ca08f06fc2e2b55269ffbbf7dedad00a8bdb Mon Sep 17 00:00:00 2001
From: Karthika Devi C <quic_kartc at quicinc.com>
Date: Wed, 13 Dec 2023 00:32:10 +0530
Subject: [PATCH 2/4] Removed target details in test file.

---
 polly/test/ScheduleOptimizer/schedule_computeout.ll | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/polly/test/ScheduleOptimizer/schedule_computeout.ll b/polly/test/ScheduleOptimizer/schedule_computeout.ll
index 3e768e02c8a740..db46ef5021932c 100644
--- a/polly/test/ScheduleOptimizer/schedule_computeout.ll
+++ b/polly/test/ScheduleOptimizer/schedule_computeout.ll
@@ -2,9 +2,6 @@
 ; Bailout if the computations of schedule compute exceeds the max scheduling quota.
 ; Max compute out is initialized to 300000, Here it is set to 100000 for test purpose.
 
-target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
-target triple = "aarch64-unknown-linux-gnu"
-
 @a = dso_local local_unnamed_addr global ptr null, align 8
 @b = dso_local local_unnamed_addr global ptr null, align 8
 @c = dso_local local_unnamed_addr global ptr null, align 8

>From 7c7497d3217691cf8e4801a770698e12090e06a2 Mon Sep 17 00:00:00 2001
From: Karthika Devi C <quic_kartc at quicinc.com>
Date: Wed, 13 Dec 2023 20:44:59 +0530
Subject: [PATCH 3/4] Update ScheduleOptimizer.cpp

---
 polly/lib/Transform/ScheduleOptimizer.cpp | 25 ++++++++---------------
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/polly/lib/Transform/ScheduleOptimizer.cpp b/polly/lib/Transform/ScheduleOptimizer.cpp
index 8ee2b66339adbc..bd29e80e8792a7 100644
--- a/polly/lib/Transform/ScheduleOptimizer.cpp
+++ b/polly/lib/Transform/ScheduleOptimizer.cpp
@@ -868,23 +868,16 @@ static void runIslScheduleOptimizer(
     SC = SC.set_validity(Validity);
     SC = SC.set_coincidence(Validity);
 
-    // Save error handling behavior
-    long MaxOperations = isl_ctx_get_max_operations(Ctx);
-    isl_ctx_set_max_operations(Ctx, ScheduleComputeOut);
-    Schedule = SC.compute_schedule();
-    bool ScheduleQuota = false;
-    if (isl_ctx_last_error(Ctx) == isl_error_quota) {
-      isl_ctx_reset_error(Ctx);
-      LLVM_DEBUG(
-          dbgs() << "Schedule optimizer calculation exceeds ISL quota\n");
-      ScheduleQuota = true;
+    {
+      IslMaxOperationsGuard MaxOpGuard(Ctx, ScheduleComputeOut);
+      Schedule = SC.compute_schedule();
+
+      if (MaxOpGuard.hasQuotaExceeded()) {
+        LLVM_DEBUG(
+            dbgs() << "Schedule optimizer calculation exceeds ISL quota\n");
+        return;
+      }
     }
-    isl_options_set_on_error(Ctx, ISL_ON_ERROR_ABORT);
-    isl_ctx_reset_operations(Ctx);
-    isl_ctx_set_max_operations(Ctx, MaxOperations);
-
-    if (ScheduleQuota)
-      return;
 
     isl_options_set_on_error(Ctx, OnErrorStatus);
 

>From 7d21eabcc58b5cf04433ab56968be54da906d03b Mon Sep 17 00:00:00 2001
From: Karthika Devi C <quic_kartc at quicinc.com>
Date: Tue, 19 Dec 2023 13:33:06 +0530
Subject: [PATCH 4/4] Update ScheduleOptimizer.cpp

---
 polly/lib/Transform/ScheduleOptimizer.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/polly/lib/Transform/ScheduleOptimizer.cpp b/polly/lib/Transform/ScheduleOptimizer.cpp
index bd29e80e8792a7..5a0ea3b4067542 100644
--- a/polly/lib/Transform/ScheduleOptimizer.cpp
+++ b/polly/lib/Transform/ScheduleOptimizer.cpp
@@ -872,11 +872,9 @@ static void runIslScheduleOptimizer(
       IslMaxOperationsGuard MaxOpGuard(Ctx, ScheduleComputeOut);
       Schedule = SC.compute_schedule();
 
-      if (MaxOpGuard.hasQuotaExceeded()) {
+      if (MaxOpGuard.hasQuotaExceeded())
         LLVM_DEBUG(
             dbgs() << "Schedule optimizer calculation exceeds ISL quota\n");
-        return;
-      }
     }
 
     isl_options_set_on_error(Ctx, OnErrorStatus);



More information about the cfe-commits mailing list