[DeLICM] Fix unused zone for writes without in-between read.

The implementation of computeArrayUnused did not consider writes without
reads before, except for the first write in the SCoP. This caused it to
'forget' writes directly following another write.

This patch re-adds the entire reaching defintion of a write that has not
been covered before by a read.

This fixes Polybench 4.2 2mm where only one of the matrix-multiplication
was detected.

llvm-svn: 311403
This commit is contained in:
Michael Kruse 2017-08-21 23:04:45 +00:00
parent 7d449d31a4
commit ade14269cd
2 changed files with 23 additions and 11 deletions

View File

@ -366,13 +366,6 @@ polly::computeArrayUnused(isl::union_map Schedule, isl::union_map Writes,
auto WriteActions =
give(isl_union_map_apply_domain(Schedule.copy(), Writes.copy()));
// { [Element[] -> Scatter[] }
auto AfterReads = afterScatter(ReadActions, ReadEltInSameInst);
auto WritesBeforeAnyReads =
give(isl_union_map_subtract(WriteActions.take(), AfterReads.take()));
auto BeforeWritesBeforeAnyReads =
beforeScatter(WritesBeforeAnyReads, !IncludeWrite);
// { [Element[] -> DomainWrite[]] -> Scatter[] }
auto EltDomWrites = give(isl_union_map_apply_range(
isl_union_map_range_map(isl_union_map_reverse(Writes.copy())),
@ -390,15 +383,26 @@ polly::computeArrayUnused(isl::union_map Schedule, isl::union_map Writes,
auto ReadsOverwrittenRotated = give(isl_union_map_reverse(
isl_union_map_curry(reverseDomain(ReadsOverwritten).take())));
auto LastOverwrittenRead =
give(isl_union_map_lexmax(ReadsOverwrittenRotated.take()));
give(isl_union_map_lexmax(ReadsOverwrittenRotated.copy()));
// { [Element[] -> DomainWrite[]] -> Scatter[] }
auto BetweenLastReadOverwrite = betweenScatter(
LastOverwrittenRead, EltDomWrites, IncludeLastRead, IncludeWrite);
return give(isl_union_map_union(
BeforeWritesBeforeAnyReads.take(),
isl_union_map_domain_factor_domain(BetweenLastReadOverwrite.take())));
// { [Element[] -> Scatter[]] -> DomainWrite[] }
isl::union_map ReachingOverwriteZone = computeReachingWrite(
Schedule, Writes, true, IncludeLastRead, IncludeWrite);
// { [Element[] -> DomainWrite[]] -> Scatter[] }
isl::union_map ReachingOverwriteRotated =
reverseDomain(ReachingOverwriteZone).curry().reverse();
// { [Element[] -> DomainWrite[]] -> Scatter[] }
isl::union_map WritesWithoutReads = ReachingOverwriteRotated.subtract_domain(
ReadsOverwrittenRotated.domain());
return BetweenLastReadOverwrite.unite(WritesWithoutReads)
.domain_factor_domain();
}
isl::union_set polly::convertZoneToTimepoints(isl::union_set Zone,

View File

@ -783,6 +783,14 @@ TEST(DeLICM, computeArrayUnused) {
computeArrayUnused(UMAP("{ Write[] -> [0] }"),
UMAP("{ Write[] -> Elt[] }"), UMAP("{}"),
ReadEltInSameInst, false, true));
// read, write, write
EXPECT_EQ(
UMAP("{ Elt[] -> [i] : 0 < i <= 20 }"),
computeArrayUnused(
UMAP("{ Read[] -> [0]; WriteA[] -> [10]; WriteB[] -> [20] }"),
UMAP("{ WriteA[] -> Elt[]; WriteB[] -> Elt[] }"),
UMAP("{ Read[] -> Elt[] }"), ReadEltInSameInst, false, true));
}
// Read and write in same statement