[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:
parent
f263610b82
commit
fa7be88378
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue