LLE 6/6: Add LoopLoadElimination pass
authorAdam Nemet <anemet@apple.com>
Tue, 3 Nov 2015 23:50:08 +0000 (23:50 +0000)
committerAdam Nemet <anemet@apple.com>
Tue, 3 Nov 2015 23:50:08 +0000 (23:50 +0000)
commitbd67564ff236b5213324980894c36eda6e3dd317
tree1fa70100b34c969a0029a4df560b1c0276c3784e
parent3410689a6f2da37ee24bd690b96528f072978e33
LLE 6/6: Add LoopLoadElimination pass

Summary:
The goal of this pass is to perform store-to-load forwarding across the
backedge of a loop.  E.g.:

  for (i)
     A[i + 1] = A[i] + B[i]

  =>

  T = A[0]
  for (i)
     T = T + B[i]
     A[i + 1] = T

The pass relies on loop dependence analysis via LoopAccessAnalisys to
find opportunities of loop-carried dependences with a distance of one
between a store and a load.  Since it's using LoopAccessAnalysis, it was
easy to also add support for versioning away may-aliasing intervening
stores that would otherwise prevent this transformation.

This optimization is also performed by Load-PRE in GVN without the
option of multi-versioning.  As was discussed with Daniel Berlin in
http://reviews.llvm.org/D9548, this is inferior to a more loop-aware
solution applied here.  Hopefully, we will be able to remove some
complexity from GVN/MemorySSA as a consequence.

In the long run, we may want to extend this pass (or create a new one if
there is little overlap) to also eliminate loop-indepedent redundant
loads and store that *require* versioning due to may-aliasing
intervening stores/loads.  I have some motivating cases for store
elimination. My plan right now is to wait for MemorySSA to come online
first rather than using memdep for this.

The main motiviation for this pass is the 456.hmmer loop in SPECint2006
where after distributing the original loop and vectorizing the top part,
we are left with the critical path exposed in the bottom loop.  Being
able to promote the memory dependence into a register depedence (even
though the HW does perform store-to-load fowarding as well) results in a
major gain (~20%).  This gain also transfers over to x86: it's
around 8-10%.

Right now the pass is off by default and can be enabled
with -enable-loop-load-elim.  On the LNT testsuite, there are two
performance changes (negative number -> improvement):

  1. -28% in Polybench/linear-algebra/solvers/dynprog: the length of the
     critical paths is reduced
  2. +2% in Polybench/stencils/adi: Unfortunately, I couldn't reproduce this
     outside of LNT

The pass is scheduled after the loop vectorizer (which is after loop
distribution).  The rational is to try to reuse LAA state, rather than
recomputing it.  The order between LV and LLE is not critical because
normally LV does not touch scalar st->ld forwarding cases where
vectorizing would inhibit the CPU's st->ld forwarding to kick in.

LoopLoadElimination requires LAA to provide the full set of dependences
(including forward dependences).  LAA is known to omit loop-independent
dependences in certain situations.  The big comment before
removeDependencesFromMultipleStores explains why this should not occur
for the cases that we're interested in.

Reviewers: dberlin, hfinkel

Subscribers: junbuml, dberlin, mssimpso, rengolin, sanjoy, llvm-commits

Differential Revision: http://reviews.llvm.org/D13259

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252017 91177308-0d34-0410-b5e6-96231b3b80d8
13 files changed:
include/llvm/Analysis/LoopAccessAnalysis.h
include/llvm/InitializePasses.h
include/llvm/Transforms/Scalar.h
lib/Transforms/IPO/PassManagerBuilder.cpp
lib/Transforms/Scalar/CMakeLists.txt
lib/Transforms/Scalar/LoopLoadElimination.cpp [new file with mode: 0644]
lib/Transforms/Scalar/Scalar.cpp
test/Transforms/LoopLoadElim/backward.ll [new file with mode: 0644]
test/Transforms/LoopLoadElim/def-store-before-load.ll [new file with mode: 0644]
test/Transforms/LoopLoadElim/forward.ll [new file with mode: 0644]
test/Transforms/LoopLoadElim/memcheck.ll [new file with mode: 0644]
test/Transforms/LoopLoadElim/multiple-stores-same-block.ll [new file with mode: 0644]
test/Transforms/LoopLoadElim/unknown-dep.ll [new file with mode: 0644]