From: Sanjoy Das Date: Tue, 15 Sep 2015 01:42:48 +0000 (+0000) Subject: [PlaceSafepoints] Make the width of a counted loop settable. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d7e1379fc2f8d01b7763cb2986686f78bc4d5455;p=oota-llvm.git [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 --- diff --git a/lib/Transforms/Scalar/PlaceSafepoints.cpp b/lib/Transforms/Scalar/PlaceSafepoints.cpp index eb1fe48f42d..1473e3db7c7 100644 --- a/lib/Transforms/Scalar/PlaceSafepoints.cpp +++ b/lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -96,8 +96,10 @@ using namespace llvm; static cl::opt AllBackedges("spp-all-backedges", cl::Hidden, cl::init(false)); -/// If true, do not place backedge safepoints in counted loops. -static cl::opt 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 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)) - return true; - if (SkipCounted && - SE->getUnsignedRange(MaxExec).getUnsignedMax().isIntN(32)) + if (MaxExec != SE->getCouldNotCompute() && + SE->getUnsignedRange(MaxExec).getUnsignedMax().isIntN( + CountedLoopTripWidth)) return true; - } } return /* not finite */ false; diff --git a/test/Transforms/PlaceSafepoints/finite-loops.ll b/test/Transforms/PlaceSafepoints/finite-loops.ll index 3cc7158afcf..9121e92896c 100644 --- a/test/Transforms/PlaceSafepoints/finite-loops.ll +++ b/test/Transforms/PlaceSafepoints/finite-loops.ll @@ -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()