[LoopFlatten] Add a loop-flattening pass
authorSjoerd Meijer <sjoerd.meijer@arm.com>
Wed, 30 Sep 2020 10:16:22 +0000 (11:16 +0100)
committerSjoerd Meijer <sjoerd.meijer@arm.com>
Thu, 1 Oct 2020 12:54:45 +0000 (13:54 +0100)
commitd53b4bee0ccd408cfe6e592540858046244e74ce
tree0885bc08b43c985097f68cce7f86168daeb20c7c
parent7e02bc81c6dad90b0f98f74152f4b0991087d78d
[LoopFlatten] Add a loop-flattening pass

This is a simple pass that flattens nested loops.  The intention is to optimise
loop nests like this, which together access an array linearly:

  for (int i = 0; i < N; ++i)
    for (int j = 0; j < M; ++j)
      f(A[i*M+j]);

into one loop:

  for (int i = 0; i < (N*M); ++i)
    f(A[i]);

It can also flatten loops where the induction variables are not used in the
loop. This can help with codesize and runtime, especially on simple cpus
without advanced branch prediction.

This is only worth flattening if the induction variables are only used in an
expression like i*M+j. If they had any other uses, we would have to insert a
div/mod to reconstruct the original values, so this wouldn't be profitable.

This partially fixes PR40581 as this pass triggers on one of the two cases. I
will follow up on this to learn LoopFlatten a few more (small) tricks. Please
note that LoopFlatten is not yet enabled by default.

Patch by Oliver Stannard, with minor tweaks from Dave Green and myself.

Differential Revision: https://reviews.llvm.org/D42365
13 files changed:
llvm/include/llvm/InitializePasses.h
llvm/include/llvm/LinkAllPasses.h
llvm/include/llvm/Transforms/Scalar.h
llvm/include/llvm/Transforms/Scalar/LoopFlatten.h [new file with mode: 0644]
llvm/lib/Passes/PassBuilder.cpp
llvm/lib/Passes/PassRegistry.def
llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
llvm/lib/Transforms/Scalar/CMakeLists.txt
llvm/lib/Transforms/Scalar/LoopFlatten.cpp [new file with mode: 0644]
llvm/lib/Transforms/Scalar/Scalar.cpp
llvm/test/Transforms/LoopFlatten/loop-flatten-negative.ll [new file with mode: 0644]
llvm/test/Transforms/LoopFlatten/loop-flatten.ll [new file with mode: 0644]
llvm/test/Transforms/LoopFlatten/pr40581.ll [new file with mode: 0644]