[PATCH] D13697: [SimplifyCFG] Merge conditional stores

James Molloy via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 13 07:30:15 PDT 2015


jmolloy created this revision.
jmolloy added reviewers: sanjoy, majnemer.
jmolloy added a subscriber: llvm-commits.
jmolloy set the repository for this revision to rL LLVM.

We can often end up with conditional stores that cannot be speculated. They can come from fairly simple, idiomatic code:

  if (c & flag1)
    *a = x;
  if (c & flag2)
    *a = y;
  ...

There is no dominating or post-dominating store to a, so it is not legal to move the store unconditionally to the end of the sequence and cache the intermediate result in a register, as we would like to.

It is, however, legal to merge the stores together and do the store once:

  tmp = undef;
  if (c & flag1)
    tmp = x;
  if (c & flag2)
    tmp = y;
  if (c & flag1 || c & flag2)
    *a = tmp;

The real power in this optimization is that it allows arbitrary length ladders such as these to be completely and trivially if-converted. The typical code I'd expect this to trigger on often uses binary-AND with constants as the condition (as in the above example), which means the ending condition can simply be truncated into a single binary-AND too: 'if (c & (flag1|flag2))'. As in the general case there are bitwise operators here, the ladder can often be optimized further too.

This optimization involves potentially increasing register pressure. Even in the simplest case, the lifetime of the first predicate is extended. This can be elided in some cases such as using binary-AND on constants, but not in the general case. Threading 'tmp' through all branches can also increase register pressure.

The optimization as in this patch is enabled by default but kept in a very conservative mode. It will only optimize if it thinks the resultant code should be if-convertable, and additionally if it can thread 'tmp' through at least one existing PHI, so it will only ever in the worst case create one more PHI and extend the lifetime of a predicate.

This doesn't trigger much in LNT, unfortunately, but it does trigger in a big way in a third party test suite.

LNT diff: one test regresses by 2%, another improves by 3%.

Repository:
  rL LLVM

http://reviews.llvm.org/D13697

Files:
  include/llvm/Transforms/Utils/Local.h
  lib/Transforms/Scalar/SimplifyCFGPass.cpp
  lib/Transforms/Utils/SimplifyCFG.cpp
  test/Transforms/SimplifyCFG/merge-cond-stores.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13697.37250.patch
Type: text/x-patch
Size: 28270 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151013/4ed2734d/attachment.bin>


More information about the llvm-commits mailing list