[Simplify] Remove identical write removal. NFC.

Removal of overwritten writes currently encompasses all the cases
of the identical write removal.

There is an observable behavioral change in that the last, instead
of the first, MemoryAccess is kept. This should not affect the
generated code, however.

Differential Revision: https://reviews.llvm.org/D33143

llvm-svn: 302987
This commit is contained in:
Michael Kruse 2017-05-13 12:20:57 +00:00
parent f263610b82
commit fa7be88378
7 changed files with 8 additions and 88 deletions

View File

@ -31,8 +31,6 @@ STATISTIC(PairUnequalAccRels, "Number of Load-Store pairs NOT removed because "
"of different access relations");
STATISTIC(InBetweenStore, "Number of Load-Store pairs NOT removed because "
"there is another store between them");
STATISTIC(TotalIdenticalWritesRemoved,
"Number of double writes removed in any SCoP");
STATISTIC(TotalOverwritesRemoved, "Number of removed overwritten writes");
STATISTIC(TotalRedundantWritesRemoved,
"Number of writes of same value removed in any SCoP");
@ -106,9 +104,6 @@ private:
/// The last/current SCoP that is/has been processed.
Scop *S;
/// Number of double writes removed from this SCoP.
int IdenticalWritesRemoved = 0;
/// Number of writes that are overwritten anyway.
int OverwritesRemoved = 0;
@ -120,8 +115,8 @@ private:
/// Return whether at least one simplification has been applied.
bool isModified() const {
return IdenticalWritesRemoved > 0 || OverwritesRemoved > 0 ||
RedundantWritesRemoved > 0 || StmtsRemoved > 0;
return OverwritesRemoved > 0 || RedundantWritesRemoved > 0 ||
StmtsRemoved > 0;
}
MemoryAccess *getReadAccessForValue(ScopStmt *Stmt, llvm::Value *Val) {
@ -195,75 +190,6 @@ private:
return nullptr;
}
/// If there are two writes in the same statement that write the same value to
/// the same location, remove one of them.
///
/// This currently handles only implicit writes (writes which logically occur
/// at the end of a statement when all StoreInst and LoadInst have been
/// executed), to avoid interference with other memory accesses.
///
/// Two implicit writes have no defined order. It can be produced by DeLICM
/// when it determined that both write the same value.
void removeIdenticalWrites() {
for (auto &Stmt : *S) {
// Delay actual removal to not invalidate iterators.
SmallPtrSet<MemoryAccess *, 4> StoresToRemove;
auto Domain = give(Stmt.getDomain());
// TODO: This has quadratic runtime. Accesses could be grouped by
// getAccessValue() to avoid.
for (auto *WA1 : Stmt) {
if (!WA1->isMustWrite())
continue;
if (!WA1->isOriginalScalarKind())
continue;
if (StoresToRemove.count(WA1))
continue;
auto *WrittenScalar1 = getWrittenScalar(WA1);
if (!WrittenScalar1)
continue;
for (auto *WA2 : Stmt) {
if (WA1 == WA2)
continue;
if (!WA2->isMustWrite())
continue;
if (!WA2->isOriginalScalarKind())
continue;
if (StoresToRemove.count(WA2))
continue;
auto *WrittenScalar2 = getWrittenScalar(WA2);
if (WrittenScalar1 != WrittenScalar2)
continue;
auto AccRel1 = give(isl_map_intersect_domain(WA1->getAccessRelation(),
Domain.copy()));
auto AccRel2 = give(isl_map_intersect_domain(WA2->getAccessRelation(),
Domain.copy()));
if (isl_map_is_equal(AccRel1.keep(), AccRel2.keep()) != isl_bool_true)
continue;
DEBUG(dbgs() << "Remove identical writes:\n");
DEBUG(dbgs() << " First write (kept) : " << WA1 << '\n');
DEBUG(dbgs() << " Second write (removed): " << WA2 << '\n');
StoresToRemove.insert(WA2);
}
}
for (auto *WA : StoresToRemove) {
auto *Stmt = WA->getStatement();
Stmt->removeSingleMemoryAccess(WA);
IdenticalWritesRemoved++;
TotalIdenticalWritesRemoved++;
}
}
}
/// Remove writes that are overwritten unconditionally later in the same
/// statement.
///
@ -408,8 +334,6 @@ private:
/// Print simplification statistics to @p OS.
void printStatistics(llvm::raw_ostream &OS, int Indent = 0) const {
OS.indent(Indent) << "Statistics {\n";
OS.indent(Indent + 4) << "Identical writes removed: "
<< IdenticalWritesRemoved << '\n';
OS.indent(Indent + 4) << "Overwrites removed: " << OverwritesRemoved
<< '\n';
OS.indent(Indent + 4) << "Redundant writes removed: "
@ -446,9 +370,6 @@ public:
this->S = &S;
ScopsProcessed++;
DEBUG(dbgs() << "Removing identical writes...\n");
removeIdenticalWrites();
DEBUG(dbgs() << "Removing overwrites...\n");
removeOverwrites();
@ -481,7 +402,6 @@ public:
virtual void releaseMemory() override {
S = nullptr;
IdenticalWritesRemoved = 0;
OverwritesRemoved = 0;
RedundantWritesRemoved = 0;
StmtsRemoved = 0;

View File

@ -15,7 +15,7 @@
; A[0] = A[1];
; }
;
define void @identical_3phi(i32 %n, double* noalias nonnull %A) {
define void @overwritten_3phi(i32 %n, double* noalias nonnull %A) {
entry:
br label %for
@ -51,11 +51,11 @@ return:
; CHECK: Statistics {
; CHECK: Identical writes removed: 2
; CHECK: Overwrites removed: 2
; CHECK: }
; CHECK: Stmt_body
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_body[i0] -> MemRef_phi1__phi[] };
; CHECK-NEXT: [n] -> { Stmt_body[i0] -> MemRef_phi3__phi[] };
; CHECK-NEXT: new: [n] -> { Stmt_body[i0] -> MemRef_A[1] };
; CHECK-NEXT: Stmt_user

View File

@ -14,7 +14,7 @@
; A[0] = A[1];
; }
;
define void @identical(i32 %n, double* noalias nonnull %A) {
define void @overwritten_scalar(i32 %n, double* noalias nonnull %A) {
entry:
br label %for
@ -46,11 +46,11 @@ return:
; CHECK: Statistics {
; CHECK: Identical writes removed: 1
; CHECK: Overwrites removed: 1
; CHECK: }
; CHECK: Stmt_body
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_body[i0] -> MemRef_phi__phi[] };
; CHECK-NEXT: [n] -> { Stmt_body[i0] -> MemRef_val[] };
; CHECK-NEXT: new: [n] -> { Stmt_body[i0] -> MemRef_A[1] };
; CHECK-NEXT: Stmt_user