Skip to content
This repository was archived by the owner on Apr 28, 2023. It is now read-only.

Commit d88661b

Browse files
committed
Scop: separate may and must writes
Originally, TC did not support indirection on the LHS. From the polyhedral representation point of view, all writes were thus "must" writes, that is the tensor elements were necessarily overwritten. With indirection, it is impossible to decide statically which elements will be overwritten and which ones won't. Therefore, we need to separately consider "may" writes, i.e. the elements that may or may not be written depending on some dynamic values, and "must" writes. Introduce may/must write separation at the Scop level. Treat all writes as may writes, which is safe may lead to inefficient schedules.
1 parent 263eec2 commit d88661b

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

include/tc/core/polyhedral/scop.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ struct Scop {
6666
res->globalParameterContext = scop.globalParameterContext;
6767
res->halide = scop.halide;
6868
res->reads = scop.reads;
69-
res->writes = scop.writes;
69+
res->mayWrites = scop.mayWrites;
70+
res->mustWrites = scop.mustWrites;
7071
res->scheduleTreeUPtr =
7172
detail::ScheduleTree::makeScheduleTree(*scop.scheduleTreeUPtr);
7273
res->treeSyncUpdateMap = scop.treeSyncUpdateMap;
@@ -115,7 +116,8 @@ struct Scop {
115116
void specializeToContext() {
116117
domain() = domain().intersect_params(globalParameterContext);
117118
reads = reads.intersect_params(globalParameterContext);
118-
writes = writes.intersect_params(globalParameterContext);
119+
mayWrites = mayWrites.intersect_params(globalParameterContext);
120+
mustWrites = mustWrites.intersect_params(globalParameterContext);
119121
}
120122

121123
// Returns a set that specializes the named scop's subset of
@@ -442,8 +444,14 @@ struct Scop {
442444
// This globalParameterContext lives in a parameter space.
443445
isl::set globalParameterContext; // TODO: not too happy about this name
444446

447+
// Access relations.
448+
// Elements in mayWrite may or may not be written by the execution, depending
449+
// on some dynamic condition. Those in mustWrites are always written.
450+
// Thefore, mayWrites do not participate in transitively-covered dependence
451+
// removal.
445452
isl::union_map reads;
446-
isl::union_map writes;
453+
isl::union_map mayWrites;
454+
isl::union_map mustWrites;
447455

448456
private:
449457
// By analogy with generalized functions, a ScheduleTree is a (piecewise

src/core/polyhedral/memory_promotion.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ TensorGroups TensorReferenceGroup::accessedBySubtree(
348348
auto schedule = partialSchedule(scop.scheduleRoot(), tree);
349349

350350
addSingletonReferenceGroups(
351-
tensorGroups, scop.writes, domain, schedule, AccessType::Write);
351+
tensorGroups, scop.mayWrites, domain, schedule, AccessType::Write);
352352
addSingletonReferenceGroups(
353353
tensorGroups, scop.reads, domain, schedule, AccessType::Read);
354354

src/core/polyhedral/scop.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ ScopUPtr Scop::makeScop(
6666
auto tree = halide2isl::makeScheduleTree(paramSpace, components.stmt);
6767
scop->scheduleTreeUPtr = std::move(tree.tree);
6868
scop->reads = tree.reads;
69-
scop->writes = tree.writes;
69+
scop->mayWrites = tree.writes;
70+
scop->mustWrites = isl::union_map::empty(scop->mayWrites.get_space());
7071
scop->halide.statements = std::move(tree.statements);
7172
scop->halide.accesses = std::move(tree.accesses);
7273
scop->halide.reductions = halide2isl::findReductions(components.stmt);
@@ -114,7 +115,8 @@ const isl::union_set Scop::domain() const {
114115
std::ostream& operator<<(std::ostream& os, const Scop& s) {
115116
os << "domain: " << s.domain() << "\n";
116117
os << "reads: " << s.reads << "\n";
117-
os << "writes: " << s.writes << "\n";
118+
os << "mayWrites: " << s.mayWrites << "\n";
119+
os << "mustWrites: " << s.mustWrites << "\n";
118120
os << "schedule: " << *s.scheduleRoot() << "\n";
119121
os << "idx: { ";
120122
for (auto i : s.halide.idx) {
@@ -378,7 +380,7 @@ isl::schedule_constraints makeScheduleConstraints(
378380
auto schedule = toIslSchedule(scop.scheduleRoot());
379381
auto firstChildNode = scop.scheduleRoot()->child({0});
380382
auto reads = scop.reads.domain_factor_domain();
381-
auto writes = scop.writes.domain_factor_domain();
383+
auto writes = scop.mayWrites.domain_factor_domain();
382384

383385
// RAW
384386
auto flowDeps = computeDependences(writes, reads, schedule);

0 commit comments

Comments
 (0)