[polly] Isl ast gen compute out (PR #201859)
Shikhar Jain via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 24 08:50:23 PDT 2026
https://github.com/ShikharJ-Corp updated https://github.com/llvm/llvm-project/pull/201859
>From 182378bbc4b0ee4d0d5baf65f3acd99b50187fea Mon Sep 17 00:00:00 2001
From: ShikharJain <shikharj at qti.qualcomm.com>
Date: Wed, 10 Jun 2026 21:31:10 -0700
Subject: [PATCH 1/2] [Polly] Bound ISL operations during AST generation to
prevent indefinite compile time
When -polly-process-unprofitable is used, this allows
SCoPs with complex iteration domains to reach ISL AST generation.
This patch applies IslMaxOperationsGuard around
isl_ast_build_node_from_schedule() in IslAst::init().
A new flag polly-astgen-computeout (default 3000000) controls
the limit.
Fixes:https://github.com/llvm/llvm-project/issues/201801
---
polly/lib/CodeGen/IslAst.cpp | 26 ++++-
polly/test/IstAstInfo/AstGenComputeOut.ll | 110 ++++++++++++++++++++++
2 files changed, 132 insertions(+), 4 deletions(-)
create mode 100644 polly/test/IstAstInfo/AstGenComputeOut.ll
diff --git a/polly/lib/CodeGen/IslAst.cpp b/polly/lib/CodeGen/IslAst.cpp
index 0ea14ae2fc2e0..208722a701665 100644
--- a/polly/lib/CodeGen/IslAst.cpp
+++ b/polly/lib/CodeGen/IslAst.cpp
@@ -86,6 +86,11 @@ static cl::opt<bool>
cl::desc("Print the ISL abstract syntax tree"),
cl::cat(PollyCategory));
+static cl::opt<unsigned long>
+ AstGenComputeout("polly-astgen-computeout",
+ cl::desc("Bound the AST generation by a maximal number of "
+ "ISL operations [0 means un-bounded]"),
+ cl::Hidden, cl::init(3000000), cl::cat(PollyCategory));
STATISTIC(ScopsProcessed, "Number of SCoPs processed");
STATISTIC(ScopsBeneficial, "Number of beneficial SCoPs");
STATISTIC(BeneficialAffineLoops, "Number of beneficial affine loops");
@@ -545,10 +550,23 @@ void IslAst::init(const Dependences &D) {
}
RunCondition = buildRunCondition(S, isl::manage_copy(Build));
-
- Root = isl::manage(
- isl_ast_build_node_from_schedule(Build, S.getScheduleTree().release()));
- walkAstForStatistics(Root);
+ // Apply IslMaxOperationsGuard on the api which starts the process of ASt gen
+ // from schedule tree. This is to avoid the timeout when the schedule tree is
+ // too big and complex.
+
+ {
+ IslMaxOperationsGuard MaxOpGuard(Ctx.get(), AstGenComputeout);
+ Root = isl::manage(
+ isl_ast_build_node_from_schedule(Build, S.getScheduleTree().release()));
+ if (MaxOpGuard.hasQuotaExceeded()) {
+ POLLY_DEBUG(
+ dbgs() << "AST generation for SCoP in function '"
+ << S.getFunction().getName()
+ << "' exceeded operation limit (operations). Skipping.\n");
+ }
+ }
+ if (!Root.is_null())
+ walkAstForStatistics(Root);
isl_ast_build_free(Build);
}
diff --git a/polly/test/IstAstInfo/AstGenComputeOut.ll b/polly/test/IstAstInfo/AstGenComputeOut.ll
new file mode 100644
index 0000000000000..d846849f24c93
--- /dev/null
+++ b/polly/test/IstAstInfo/AstGenComputeOut.ll
@@ -0,0 +1,110 @@
+; RUN: opt %s -passes='polly-custom<ast>' -polly-process-unprofitable \
+; RUN: -polly-astgen-computeout=1000000 -debug-only=polly-ast \
+; RUN: -disable-output 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "aarch64-unknown-linux-gnueabi"
+
+define void @InitializeZeroMasks(i32 %0) {
+entry:
+ br label %if.end
+
+if.end: ; preds = %for.inc18, %entry
+ %indvars.iv = phi i64 [ 1, %entry ], [ %indvars.iv.next, %for.inc18 ]
+ br i1 true, label %if.end.1, label %for.end
+
+if.end.1: ; preds = %if.end
+ %tobool.not.14 = icmp eq i32 %0, 0
+ br i1 %tobool.not.14, label %if.end.14, label %for.end
+
+if.end.14: ; preds = %if.end.1
+ %1 = trunc i64 %indvars.iv to i32
+ %and.15 = and i32 %1, 1
+ %tobool.not.15 = icmp eq i32 %and.15, 0
+ br i1 %tobool.not.15, label %if.end14, label %for.end
+
+for.end: ; preds = %if.end.14, %if.end.1, %if.end
+ %j.0119.lcssa = phi i8 [ 0, %if.end.1 ], [ 1, %if.end ], [ 0, %if.end.14 ]
+ br label %if.then10
+
+if.then10: ; preds = %if.end14.13, %if.end14.12, %if.end14.11, %if.end14.10, %if.end14.9, %if.end14.8, %if.end14.7, %if.end14.6, %if.end14.5, %if.end14.4, %if.end14.3, %if.end14.2, %if.end14, %for.end
+ %j.1121.lcssa.neg = phi i8 [ 1, %for.end ], [ 0, %if.end14 ], [ 0, %if.end14.13 ], [ 0, %if.end14.2 ], [ 0, %if.end14.3 ], [ 0, %if.end14.4 ], [ 0, %if.end14.5 ], [ 0, %if.end14.6 ], [ 0, %if.end14.7 ], [ 0, %if.end14.8 ], [ 0, %if.end14.9 ], [ 0, %if.end14.10 ], [ 0, %if.end14.11 ], [ 0, %if.end14.12 ]
+ store i8 0, ptr null, align 1
+ br label %for.inc18
+
+if.end14: ; preds = %if.end.14
+ %and8.1 = and i32 %1, 2
+ %tobool9.not.1 = icmp eq i32 %and8.1, 0
+ %and8.2 = and i32 %1, 4
+ %tobool9.not.2 = icmp eq i32 %and8.2, 0
+ %or.cond = and i1 %tobool9.not.1, %tobool9.not.2
+ br i1 %or.cond, label %if.end14.2, label %if.then10
+
+if.end14.2: ; preds = %if.end14
+ %and8.3 = and i32 %1, 8
+ %tobool9.not.3 = icmp eq i32 %and8.3, 0
+ br i1 %tobool9.not.3, label %if.end14.3, label %if.then10
+
+if.end14.3: ; preds = %if.end14.2
+ %and8.4 = and i32 %1, 16
+ %tobool9.not.4 = icmp eq i32 %and8.4, 0
+ br i1 %tobool9.not.4, label %if.end14.4, label %if.then10
+
+if.end14.4: ; preds = %if.end14.3
+ %and8.5 = and i32 %1, 32
+ %tobool9.not.5 = icmp eq i32 %and8.5, 0
+ br i1 %tobool9.not.5, label %if.end14.5, label %if.then10
+
+if.end14.5: ; preds = %if.end14.4
+ %and8.6 = and i32 %1, 64
+ %tobool9.not.6 = icmp eq i32 %and8.6, 0
+ br i1 %tobool9.not.6, label %if.end14.6, label %if.then10
+
+if.end14.6: ; preds = %if.end14.5
+ %and8.7 = and i32 %1, 128
+ %tobool9.not.7 = icmp eq i32 %and8.7, 0
+ br i1 %tobool9.not.7, label %if.end14.7, label %if.then10
+
+if.end14.7: ; preds = %if.end14.6
+ %and8.8 = and i32 %1, 256
+ %tobool9.not.8 = icmp eq i32 %and8.8, 0
+ br i1 %tobool9.not.8, label %if.end14.8, label %if.then10
+
+if.end14.8: ; preds = %if.end14.7
+ %and8.9 = and i32 %1, 512
+ %tobool9.not.9 = icmp eq i32 %and8.9, 0
+ br i1 %tobool9.not.9, label %if.end14.9, label %if.then10
+
+if.end14.9: ; preds = %if.end14.8
+ %and8.10 = and i32 %1, 1024
+ %tobool9.not.10 = icmp eq i32 %and8.10, 0
+ br i1 %tobool9.not.10, label %if.end14.10, label %if.then10
+
+if.end14.10: ; preds = %if.end14.9
+ %and8.11 = and i32 %1, 2048
+ %tobool9.not.11 = icmp eq i32 %and8.11, 0
+ br i1 %tobool9.not.11, label %if.end14.11, label %if.then10
+
+if.end14.11: ; preds = %if.end14.10
+ %and8.12 = and i32 %1, 4096
+ %tobool9.not.12 = icmp eq i32 %and8.12, 0
+ br i1 %tobool9.not.12, label %if.end14.12, label %if.then10
+
+if.end14.12: ; preds = %if.end14.11
+ %and8.13 = and i32 %1, 8192
+ %tobool9.not.13 = icmp eq i32 %and8.13, 0
+ br i1 %tobool9.not.13, label %if.end14.13, label %if.then10
+
+if.end14.13: ; preds = %if.end14.12
+ br i1 false, label %for.inc18, label %if.then10
+
+for.inc18: ; preds = %if.end14.13, %if.then10
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv, 65536
+ br i1 %exitcond.not, label %for.end20, label %if.end
+
+for.end20: ; preds = %for.inc18
+ ret void
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
>From ecff189d03e0f4e722abaf50a41d97a773a7ec93 Mon Sep 17 00:00:00 2001
From: Shikhar Jain <shikharj at qti.qualcomm.com>
Date: Wed, 24 Jun 2026 21:20:13 +0530
Subject: [PATCH 2/2] Update polly/lib/CodeGen/IslAst.cpp
Co-authored-by: Michael Kruse <github at meinersbur.de>
---
polly/lib/CodeGen/IslAst.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/polly/lib/CodeGen/IslAst.cpp b/polly/lib/CodeGen/IslAst.cpp
index 208722a701665..ed8dc2ff4c25b 100644
--- a/polly/lib/CodeGen/IslAst.cpp
+++ b/polly/lib/CodeGen/IslAst.cpp
@@ -550,7 +550,7 @@ void IslAst::init(const Dependences &D) {
}
RunCondition = buildRunCondition(S, isl::manage_copy(Build));
- // Apply IslMaxOperationsGuard on the api which starts the process of ASt gen
+ // Apply IslMaxOperationsGuard on the API which starts the process of AST gen
// from schedule tree. This is to avoid the timeout when the schedule tree is
// too big and complex.
More information about the llvm-commits
mailing list