[CodeGen] Support partial write accesses.
Allow the BlockGenerator to generate memory writes that are not defined
over the complete statement domain, but only over a subset of it. It
generates a condition that evaluates to 1 if executing the subdomain,
and only then execute the access.
Only write accesses are supported. Read accesses would require a PHINode
which has a value if the access is not executed.
Partial write makes DeLICM able to apply mappings that are not defined
over the entire domain (for instance, a branch that leaves a loop with
a PHINode in its header; a MemoryKind::PHI write when leaving is never
read by its PHI read).
Differential Revision: https://reviews.llvm.org/D33255
llvm-svn: 303517
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index b01d774..8937c98 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -1204,15 +1204,19 @@
isl_space_free(NewDomainSpace);
isl_space_free(OriginalDomainSpace);
- // Check whether there is an access for every statement instance.
- auto *StmtDomain = getStatement()->getDomain();
- StmtDomain = isl_set_intersect_params(
- StmtDomain, getStatement()->getParent()->getContext());
- auto *NewDomain = isl_map_domain(isl_map_copy(NewAccess));
- assert(isl_set_is_subset(StmtDomain, NewDomain) &&
- "Partial accesses not supported");
- isl_set_free(NewDomain);
- isl_set_free(StmtDomain);
+ // Reads must be executed unconditionally. Writes might be executed in a
+ // subdomain only.
+ if (isRead()) {
+ // Check whether there is an access for every statement instance.
+ auto *StmtDomain = getStatement()->getDomain();
+ StmtDomain = isl_set_intersect_params(
+ StmtDomain, getStatement()->getParent()->getContext());
+ auto *NewDomain = isl_map_domain(isl_map_copy(NewAccess));
+ assert(isl_set_is_subset(StmtDomain, NewDomain) &&
+ "Partial READ accesses not supported");
+ isl_set_free(NewDomain);
+ isl_set_free(StmtDomain);
+ }
auto *NewAccessSpace = isl_space_range(NewSpace);
assert(isl_space_has_tuple_id(NewAccessSpace, isl_dim_set) &&
@@ -1243,6 +1247,13 @@
NewAccessRelation = NewAccess;
}
+bool MemoryAccess::isLatestPartialAccess() const {
+ isl::set StmtDom = give(getStatement()->getDomain());
+ isl::set AccDom = give(isl_map_domain(getLatestAccessRelation()));
+
+ return isl_set_is_subset(StmtDom.keep(), AccDom.keep()) == isl_bool_false;
+}
+
//===----------------------------------------------------------------------===//
__isl_give isl_map *ScopStmt::getSchedule() const {