From 313c130b77e12d533b85c6195d7c4b2acbc649fa Mon Sep 17 00:00:00 2001 From: zoecarver Date: Sun, 19 Apr 2020 12:58:23 -0700 Subject: [PATCH] [LVA] Don't invalidate reads/writes that don't alias any tracked values. In DSE and RLE any unkown read/write often causes most if not all tracked values to be invalidated. This doesn't need to be the case. If the tracked value doesn't alias any of the operands of the unkown instruction, then we can safely keep the tracked value validated. --- .../Transforms/DeadStoreElimination.cpp | 14 ++++++- .../Transforms/RedundantLoadElimination.cpp | 8 ++++ test/SILOptimizer/dead_store_elim.sil | 40 +++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp b/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp index 99c4ba46cf169..88ae5b243a26d 100644 --- a/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp +++ b/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp @@ -1087,7 +1087,12 @@ void DSEContext::processUnknownReadInstForGenKillSet(SILInstruction *I) { for (unsigned i = 0; i < S->LocationNum; ++i) { if (!S->BBMaxStoreSet.test(i)) continue; - if (!AA->mayReadFromMemory(I, LocationVault[i].getBase())) + auto val = LocationVault[i].getBase(); + if (!AA->mayReadFromMemory(I, val)) + continue; + if (llvm::all_of(I->getAllOperands(), [&AA = AA, &val](Operand &op) { + return AA->isNoAlias(op.get(), val); + })) continue; // Update the genset and kill set. S->startTrackingLocation(S->BBKillSet, i); @@ -1100,7 +1105,12 @@ void DSEContext::processUnknownReadInstForDSE(SILInstruction *I) { for (unsigned i = 0; i < S->LocationNum; ++i) { if (!S->isTrackingLocation(S->BBWriteSetMid, i)) continue; - if (!AA->mayReadFromMemory(I, LocationVault[i].getBase())) + auto val = LocationVault[i].getBase(); + if (!AA->mayReadFromMemory(I, val)) + continue; + if (llvm::all_of(I->getAllOperands(), [&AA = AA, &val](Operand &op) { + return AA->isNoAlias(op.get(), val); + })) continue; S->stopTrackingLocation(S->BBWriteSetMid, i); } diff --git a/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp b/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp index e446ac4a53ec2..70f73fb82521a 100644 --- a/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp +++ b/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp @@ -977,6 +977,10 @@ void BlockState::processUnknownWriteInstForGenKillSet(RLEContext &Ctx, LSLocation &R = Ctx.getLocation(i); if (!AA->mayWriteToMemory(I, R.getBase())) continue; + if (llvm::all_of(I->getAllOperands(), [&AA, &R](Operand &op) { + return AA->isNoAlias(op.get(), R.getBase()); + })) + continue; // MayAlias. stopTrackingLocation(BBGenSet, i); startTrackingLocation(BBKillSet, i); @@ -996,6 +1000,10 @@ void BlockState::processUnknownWriteInstForRLE(RLEContext &Ctx, LSLocation &R = Ctx.getLocation(i); if (!AA->mayWriteToMemory(I, R.getBase())) continue; + if (llvm::all_of(I->getAllOperands(), [&AA, &R](Operand &op) { + return AA->isNoAlias(op.get(), R.getBase()); + })) + continue; // MayAlias. stopTrackingLocation(ForwardSetIn, i); stopTrackingValue(ForwardValIn, i); diff --git a/test/SILOptimizer/dead_store_elim.sil b/test/SILOptimizer/dead_store_elim.sil index 796667e1df31f..9af8a1391d573 100644 --- a/test/SILOptimizer/dead_store_elim.sil +++ b/test/SILOptimizer/dead_store_elim.sil @@ -1501,3 +1501,43 @@ bb0(%0 : $*foo): %20 = tuple() return %20 : $() } + +class Foo { + @_hasStorage @_hasInitialValue var x: Int { get set } + deinit + init() +} + +class Bar { + @_hasStorage @_hasInitialValue var x: Int { get set } + deinit + init() +} + +// CHECK-LABEL: @unknown_unrelated_read +// CHECK: store +// CHECK-NOT: store +// CHECK-LABEL: end sil function 'unknown_unrelated_read' +sil hidden @unknown_unrelated_read : $@convention(thin) (@inout Int) -> () { +bb0(%0 : $*Int): + %1 = alloc_ref $Foo + %3 = integer_literal $Builtin.Int64, 0 + %4 = struct $Int (%3 : $Builtin.Int64) + %5 = ref_element_addr %1 : $Foo, #Foo.x + store %4 to %5 : $*Int + + %10 = alloc_ref [stack] $Bar + %12 = ref_element_addr %10 : $Bar, #Bar.x + %15 = integer_literal $Builtin.Int64, 1 + %16 = struct $Int (%15 : $Builtin.Int64) + store %16 to %12 : $*Int + + set_deallocating %10 : $Bar + dealloc_ref %10 : $Bar + dealloc_ref [stack] %10 : $Bar + + copy_addr %5 to %0 : $*Int + + %20 = tuple() + return %20 : $() +}