[PATCH] D21313: Use ValueOffsetPair to enhance value reuse during SCEV expansion.

Wei Mi via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 13 16:07:39 PDT 2016


wmi created this revision.
wmi added reviewers: hfinkel, sanjoy.
wmi added subscribers: llvm-commits, davidxl, mkuper.
wmi set the repository for this revision to rL LLVM.
Herald added subscribers: mzolotukhin, sanjoy.

This patch is an expansion to http://reviews.llvm.org/D12090.

In D12090, the ExprValueMap was added to reuse existing value during SCEV expansion. However, const folding and sext/zext distribution can make the reuse difficult. I found a common case where the reuse opportunity was missed like this:

Loop lowerbound is intconst 2. Loop upperbound is a complex expr.
%lowerbound =  2                                   
%smax = select ...
%complexexpr = add nsw %i32 %smax, -1
%upperbound = sext i32 %complexexpr i64 

When we build SCEV for upperbound, %complexexpr is mapped to SCEV S1: (-1 + X smax Y) <nsw>
%upperbound is mapped to SCEV S2 = sext(S1) = sext((-1 + X smax Y) <nsw>) = (-1 + sext(X smax Y)) <nsw> (sext distribution for SCEV applied here)
Both S1 and S2 will have reuse value entries in ExprValueMap.

Then when we compute loop iteration number based on upperbound SCEV S2 and lowerbound 2: it is S2 - 2 + 1 = -2 + sext(X smax Y) (const folding applied here). Note we only have S1 and S2 in ExprValueMap so we don't have reuse entry for -2 + sext(X smax Y) or sext(X smax Y) so we have to expand "-2 + sext(X smax Y)" literally. When X and Y are also complex expression, it will produce a lot of redundent code.

The patch is proposing to save {Value, Offset} pair instead of just Value in ExprValueMap, and if a SCEV can be splitted into a stripped SCEV part plus an int offset, the mapping "stripped SCEV -> {Value, Offset}" will be added into ExprValueMap, so we won't worry missing reuse opportunity because of const folding.
 
For %upperbound which is mapped to SCEV S2 = (-1 + sext(X smax Y)), in addition to save mapping "S2 -> %upperbound" into ExprValueMap (Represented as S2 -> {%upperbound, 0}), it will split S2 into two parts: "stripped SCEV S3" + "offset -1". Here S3 is "sext(X smax Y)". Mapping "S3 -> {%upperbound, -1}" will also be saved into ExprValueMap.
 
Then when scev expander did code expansion for loop iteration number: -2 + sext(X smax Y), it will find out SCEV S3: sext(X smax Y) is in ExprValueMap (The entry: S3 -> {%upperbound, -1}), so it knows to reuse %upperbound - (-1) to represent sext(X smax Y), instead of expanding S3 literally.


Repository:
  rL LLVM

http://reviews.llvm.org/D21313

Files:
  include/llvm/Analysis/ScalarEvolution.h
  include/llvm/Analysis/ScalarEvolutionExpander.h
  lib/Analysis/ScalarEvolution.cpp
  lib/Analysis/ScalarEvolutionExpander.cpp
  test/Analysis/ScalarEvolution/scev-expander-existing-value-offset.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21313.60613.patch
Type: text/x-patch
Size: 14527 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160613/be4925d8/attachment.bin>


More information about the llvm-commits mailing list