[polly] [Polly] Reject SCoPs with an escaping scalar defined in an empty-doma… (PR #213656)
Shikhar Jain via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 3 21:38:52 PDT 2026
ShikharJ-Corp wrote:
> It's not clear to me that ScopBuilder has enough information to actually tell whether CodeGen will discard a statement. In particular, I'm not sure this interacts correctly with schedule optimizations.
Hi.. I dug into the exact ordering in buildScop, and I think the concern is addressed->
The statement's domain is empty as a parametric fact computed in buildDomains (ScopBuilder.cpp) a statement gets an empty domain precisely when it's a subset of the InvalidDomain (propagateInvalidStmtDomains, ScopInfo.cpp), i.e. it only executes for parameter values excluded by the runtime versioning condition. We test this (at ScopBuilder.cpp) using the same null-or-empty domain test that removeStmtNotInDomainMap (ScopInfo.cpp) uses to delete the statement at ScopBuilder.cpp, one line later. So we aren't predicting a CodeGen heuristic. we're reading the exact criterion Polly uses to drop the statement.
On the scheduling optimization interaction->
Our check runs in ScopBuilder::buildScop and, from an empty iteration domain, concludes that CodeGen will end up discarding the statement. That's an early-stage property being used to predict a late-stage outcome. Between those two points the isl schedule optimizer comes, whose whole purpose is to restructure statements -> reorder, tile etc..
**_So if the reasonable worry is: could scheduling change a statement's domain, or merge/reshape statements, so that "empty at buildScop" no longer corresponds to "discarded at CodeGen"?_**
--> then it doesn't apply here , cause of ordering.
The doomed statement is deleted before a schedule is ever built, so the scheduler never operates on it.
Within ScopBuilder::buildScop (polly/lib/Analysis/ScopBuilder.cpp), the order is:
- ScopBuilder::buildDomains fixes each statement's domain. **_Emptiness is a parametric fact — a statement is empty when its domain is a subset of the invalid-parameter region (ScopBuilder::propagateInvalidStmtDomains) — decided purely from the input parameters, independent of any transformation we later choose._**
- Our check (ScopBuilder::rejectDoomedEscapingValueWrites) uses the same null-or-empty domain test that Polly itself applies at the very next step.
- **_Scop::removeStmtNotInDomainMap (polly/lib/Analysis/ScopInfo.cpp) physically deletes every empty-domain statement, using exactly that test._**
- **_ScopBuilder::buildSchedule runs only after that removal, and builds the schedule solely from the statements that survived, via isl::schedule::from_domain(Stmt->getDomain()) over Scop::getStmtListFor._**
**So scheduling only ever sees survivors. It cannot resurrect a deleted statement, and it cannot manufacture iterations for an empty domain. Emptiness is invariant under every schedule transformation.**
Below are teh two passes which runs between SCoP building and CodeGen and can actually reshape statements, but they dont touch domains themselves..
- Scop::simplifySCoP (polly/lib/Analysis/ScopInfo.cpp) removes statements purely by access content. It never reads or mutates an iteration domain.
- ScopBuilder::hoistInvariantLoads (polly/lib/Analysis/ScopBuilder.cpp) only relocates invariant-load memory accesses . It also never touches domains either.
Thus Polly removes the statement before any schedule exists. Schedule optimization runs strictly downstream of that removal, so there is no interaction with the statements we reject on.
https://github.com/llvm/llvm-project/pull/213656
More information about the llvm-commits
mailing list