[PlaceSafepoints] Make the width of a counted loop settable.

Summary:
This change lets a `PlaceSafepoints` client change how wide the trip
count of a loop has to be for the loop to be considerd "counted", via
`CountedLoopTripWidth`.  It also removes the boolean `SkipCounted` flag
and the `upperTripBound` constant -- we can get the old behavior of
`SkipCounted` == `false` by setting `CountedLoopTripWidth` to `13` (2 ^
13 == 8192).

Reviewers: reames

Subscribers: llvm-commits, sanjoy

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247656 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjoy Das 2015-09-15 01:42:48 +00:00
parent 270e6f8a27
commit d7e1379fc2
2 changed files with 68 additions and 19 deletions

View File

@ -96,8 +96,10 @@ using namespace llvm;
static cl::opt<bool> AllBackedges("spp-all-backedges", cl::Hidden,
cl::init(false));
/// If true, do not place backedge safepoints in counted loops.
static cl::opt<bool> SkipCounted("spp-counted", cl::Hidden, cl::init(true));
/// How narrow does the trip count of a loop have to be to have to be considered
/// "counted"? Counted loops do not get safepoints at backedges.
static cl::opt<int> CountedLoopTripWidth("spp-counted-loop-trip-width",
cl::Hidden, cl::init(32));
// If true, split the backedge of a loop when placing the safepoint, otherwise
// split the latch block itself. Both are useful to support for
@ -255,18 +257,12 @@ static bool containsUnconditionalCallSafepoint(Loop *L, BasicBlock *Header,
/// conservatism in the analysis.
static bool mustBeFiniteCountedLoop(Loop *L, ScalarEvolution *SE,
BasicBlock *Pred) {
// Only used when SkipCounted is off
const unsigned upperTripBound = 8192;
// A conservative bound on the loop as a whole.
const SCEV *MaxTrips = SE->getMaxBackedgeTakenCount(L);
if (MaxTrips != SE->getCouldNotCompute()) {
if (SE->getUnsignedRange(MaxTrips).getUnsignedMax().ult(upperTripBound))
return true;
if (SkipCounted &&
SE->getUnsignedRange(MaxTrips).getUnsignedMax().isIntN(32))
return true;
}
if (MaxTrips != SE->getCouldNotCompute() &&
SE->getUnsignedRange(MaxTrips).getUnsignedMax().isIntN(
CountedLoopTripWidth))
return true;
// If this is a conditional branch to the header with the alternate path
// being outside the loop, we can ask questions about the execution frequency
@ -275,13 +271,10 @@ static bool mustBeFiniteCountedLoop(Loop *L, ScalarEvolution *SE,
// This returns an exact expression only. TODO: We really only need an
// upper bound here, but SE doesn't expose that.
const SCEV *MaxExec = SE->getExitCount(L, Pred);
if (MaxExec != SE->getCouldNotCompute()) {
if (SE->getUnsignedRange(MaxExec).getUnsignedMax().ult(upperTripBound))
if (MaxExec != SE->getCouldNotCompute() &&
SE->getUnsignedRange(MaxExec).getUnsignedMax().isIntN(
CountedLoopTripWidth))
return true;
if (SkipCounted &&
SE->getUnsignedRange(MaxExec).getUnsignedMax().isIntN(32))
return true;
}
}
return /* not finite */ false;

View File

@ -1,6 +1,7 @@
; Tests to ensure that we are not placing backedge safepoints in
; loops which are clearly finite.
;; RUN: opt %s -place-safepoints -S | FileCheck %s
;; RUN: opt %s -place-safepoints -spp-counted-loop-trip-width=32 -S | FileCheck %s
;; RUN: opt %s -place-safepoints -spp-counted-loop-trip-width=64 -S | FileCheck %s -check-prefix=COUNTED-64
; A simple counted loop with trivially known range
@ -69,6 +70,61 @@ exit:
ret void
}
; The range is a 64 bit value
define void @test4(i64 %upper) gc "statepoint-example" {
; CHECK-LABEL: test4
; CHECK-LABEL: entry
; CHECK: statepoint
; CHECK-LABEL: loop
; CHECK: statepoint
; COUNTED-64-LABEL: test4
; COUNTED-64-LABEL: entry
; COUNTED-64: statepoint
; COUNTED-64-LABEL: loop
; COUNTED-64-NOT: statepoint
entry:
br label %loop
loop:
%counter = phi i64 [ 0 , %entry ], [ %counter.inc , %loop ]
%counter.inc = add i64 %counter, 1
%counter.cmp = icmp slt i64 %counter.inc, %upper
br i1 %counter.cmp, label %loop, label %exit
exit:
ret void
}
; This loop can run infinitely (for %upper == INT64_MAX) so it needs a
; safepoint.
define void @test5(i64 %upper) gc "statepoint-example" {
; CHECK-LABEL: test5
; CHECK-LABEL: entry
; CHECK: statepoint
; CHECK-LABEL: loop
; CHECK: statepoint
; COUNTED-64-LABEL: test5
; COUNTED-64-LABEL: entry
; COUNTED-64: statepoint
; COUNTED-64-LABEL: loop
; COUNTED-64: statepoint
entry:
br label %loop
loop:
%counter = phi i64 [ 0 , %entry ], [ %counter.inc , %loop ]
%counter.inc = add i64 %counter, 1
%counter.cmp = icmp sle i64 %counter.inc, %upper
br i1 %counter.cmp, label %loop, label %exit
exit:
ret void
}
; This function is inlined when inserting a poll.
declare void @do_safepoint()