From 0d3d9fe1d6f8bfcea8b469a364a9cada1c625522 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 17 Aug 2020 18:52:57 +0100 Subject: [PATCH] [DSE,MemorySSA] Skip access already dominated by a killing def. If we already found a killing def (= a def that completely overwrites the location) that dominates an access, we can skip processing it further. This does not help with compile-time, but increases the number of memory accesses we can process with the same scan budget, leading to more stores being eliminated. Improvements with this change Same hash: 203 (filtered out) Remaining: 34 Metric: dse.NumFastStores Program base dom diff test-suite...rolangs-C++/family/family.test 2.00 4.00 100.0% test-suite...ProxyApps-C++/CLAMR/CLAMR.test 172.00 229.00 33.1% test-suite...ks/Prolangs-C/agrep/agrep.test 10.00 12.00 20.0% test-suite...oxyApps-C++/miniFE/miniFE.test 44.00 51.00 15.9% test-suite...marks/7zip/7zip-benchmark.test 1285.00 1474.00 14.7% test-suite...006/450.soplex/450.soplex.test 254.00 289.00 13.8% test-suite...006/447.dealII/447.dealII.test 2466.00 2798.00 13.5% test-suite...000/197.parser/197.parser.test 9.00 10.00 11.1% test-suite.../Benchmarks/nbench/nbench.test 85.00 91.00 7.1% test-suite...ce/Applications/siod/siod.test 68.00 72.00 5.9% test-suite...ications/JM/lencod/lencod.test 786.00 824.00 4.8% test-suite...6/464.h264ref/464.h264ref.test 765.00 798.00 4.3% test-suite.../Benchmarks/Ptrdist/bc/bc.test 105.00 109.00 3.8% test-suite...lications/obsequi/Obsequi.test 29.00 28.00 -3.4% test-suite...3.xalancbmk/483.xalancbmk.test 1322.00 1367.00 3.4% test-suite...chmarks/MallocBench/gs/gs.test 118.00 122.00 3.4% test-suite...T2006/401.bzip2/401.bzip2.test 60.00 62.00 3.3% test-suite...6/482.sphinx3/482.sphinx3.test 30.00 31.00 3.3% test-suite...rks/tramp3d-v4/tramp3d-v4.test 862.00 887.00 2.9% test-suite...telecomm-gsm/telecomm-gsm.test 78.00 80.00 2.6% test-suite...ediabench/gsm/toast/toast.test 78.00 80.00 2.6% test-suite.../Applications/SPASS/SPASS.test 163.00 167.00 2.5% test-suite...lications/ClamAV/clamscan.test 240.00 245.00 2.1% test-suite...006/453.povray/453.povray.test 1392.00 1419.00 1.9% test-suite...000/255.vortex/255.vortex.test 211.00 215.00 1.9% test-suite...:: External/Povray/povray.test 1295.00 1317.00 1.7% test-suite...lications/sqlite3/sqlite3.test 175.00 177.00 1.1% test-suite...T2000/256.bzip2/256.bzip2.test 99.00 100.00 1.0% test-suite...0/253.perlbmk/253.perlbmk.test 629.00 635.00 1.0% test-suite.../CINT2006/403.gcc/403.gcc.test 1183.00 1194.00 0.9% test-suite.../CINT2000/176.gcc/176.gcc.test 647.00 653.00 0.9% test-suite...ications/JM/ldecod/ldecod.test 512.00 516.00 0.8% test-suite...0.perlbench/400.perlbench.test 1026.00 1034.00 0.8% test-suite...-typeset/consumer-typeset.test 1876.00 1877.00 0.1% Geomean difference 7.3% --- .../Scalar/DeadStoreElimination.cpp | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index a757db10098..92167087483 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1787,7 +1787,8 @@ struct DSEState { // eliminated if the access is killed along all paths to the exit. Collect // the blocks with killing (=completely overwriting MemoryDefs) and check if // they cover all paths from DomAccess to any function exit. - SmallPtrSet KillingBlocks = {KillingDef->getBlock()}; + SmallPtrSet KillingDefs; + KillingDefs.insert(KillingDef->getMemoryInst()); LLVM_DEBUG({ dbgs() << " Checking for reads of " << *DomAccess; if (isa(DomAccess)) @@ -1816,6 +1817,13 @@ struct DSEState { --ScanLimit; if (isa(UseAccess)) { + if (any_of(KillingDefs, [this, UseAccess](Instruction *KI) { + return DT.properlyDominates(KI->getParent(), + UseAccess->getBlock()); + })) { + LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing block\n"); + continue; + } LLVM_DEBUG(dbgs() << "\n ... adding PHI uses\n"); PushMemUses(UseAccess); continue; @@ -1824,6 +1832,13 @@ struct DSEState { Instruction *UseInst = cast(UseAccess)->getMemoryInst(); LLVM_DEBUG(dbgs() << " (" << *UseInst << ")\n"); + if (any_of(KillingDefs, [this, UseInst](Instruction *KI) { + return DT.dominates(KI, UseInst); + })) { + LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing def\n"); + continue; + } + if (isNoopIntrinsic(cast(UseAccess))) { LLVM_DEBUG(dbgs() << " ... adding uses of intrinsic\n"); PushMemUses(UseAccess); @@ -1868,9 +1883,9 @@ struct DSEState { if (PostOrderNumbers.find(MaybeKillingBlock)->second < PostOrderNumbers.find(DomAccess->getBlock())->second) { - LLVM_DEBUG(dbgs() << " ... found killing block " - << MaybeKillingBlock->getName() << "\n"); - KillingBlocks.insert(MaybeKillingBlock); + LLVM_DEBUG(dbgs() + << " ... found killing def " << *UseInst << "\n"); + KillingDefs.insert(UseInst); } } } else @@ -1882,8 +1897,12 @@ struct DSEState { // that the location is killed (=overwritten) along all paths from DomAccess // to the exit. if (DefVisibleToCallerAfterRet) { + SmallPtrSet KillingBlocks; + for (Instruction *KD : KillingDefs) + KillingBlocks.insert(KD->getParent()); assert(!KillingBlocks.empty() && "Expected at least a single killing block"); + // Find the common post-dominator of all killing blocks. BasicBlock *CommonPred = *KillingBlocks.begin(); for (auto I = std::next(KillingBlocks.begin()), E = KillingBlocks.end();