Add a new pass "inductive range check elimination"
authorSanjoy Das <sanjoy@playingwithpointers.com>
Thu, 15 Jan 2015 20:45:46 +0000 (20:45 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Thu, 15 Jan 2015 20:45:46 +0000 (20:45 +0000)
commit0170a308ec82c59f16fa5fa91c68c04470ecc0ac
tree7663245ffb4efbbf6c7f73977d9d53835e5b5424
parent39b09ae7882a704c8e3953bc611ea90225a39cb2
Add a new pass "inductive range check elimination"

IRCE eliminates range checks of the form

  0 <= A * I + B < Length

by splitting a loop's iteration space into three segments in a way
that the check is completely redundant in the middle segment.  As an
example, IRCE will convert

  len = < known positive >
  for (i = 0; i < n; i++) {
    if (0 <= i && i < len) {
      do_something();
    } else {
      throw_out_of_bounds();
    }
  }

to

  len = < known positive >
  limit = smin(n, len)
  // no first segment
  for (i = 0; i < limit; i++) {
    if (0 <= i && i < len) { // this check is fully redundant
      do_something();
    } else {
      throw_out_of_bounds();
    }
  }
  for (i = limit; i < n; i++) {
    if (0 <= i && i < len) {
      do_something();
    } else {
      throw_out_of_bounds();
    }
  }

IRCE can deal with multiple range checks in the same loop (it takes
the intersection of the ranges that will make each of them redundant
individually).

Currently IRCE does not do any profitability analysis.  That is a
TODO.

Please note that the status of this pass is *experimental*, and it is
not part of any default pass pipeline.  Having said that, I will love
to get feedback and general input from people interested in trying
this out.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226201 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/InitializePasses.h
include/llvm/LinkAllPasses.h
include/llvm/Transforms/Scalar.h
lib/Transforms/Scalar/CMakeLists.txt
lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp [new file with mode: 0644]
lib/Transforms/Scalar/Scalar.cpp
test/Transforms/IRCE/multiple-access-no-preloop.ll [new file with mode: 0644]
test/Transforms/IRCE/single-access-no-preloop.ll [new file with mode: 0644]
test/Transforms/IRCE/single-access-with-preloop.ll [new file with mode: 0644]
test/Transforms/IRCE/unhandled.ll [new file with mode: 0644]
test/Transforms/IRCE/with-parent-loops.ll [new file with mode: 0644]