[PATCH] D17201: [SCEV] Introduce a guarded backedge taken count and use it in LAA and LV
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 11 16:56:57 PST 2016
sanjoy requested changes to this revision.
This revision now requires changes to proceed.
================
Comment at: include/llvm/Analysis/ScalarEvolution.h:557
@@ -545,1 +556,3 @@
+ /// otherwise it's all CouldNotCompute.
+ SCEVUnionPredicate Pred;
----------------
Now that you're embedding `SCEVUnionPredicate` in every
`ExitNotTakenInfo`, I'm somewhat worried about the `SmallVector<const
SCEVPredicate *, 16> Preds;` :)
Firstly, what is the typical number of predicates we see? 16 seems
higher that what I would expect.
Secondly, a better (in terms of memory consumption) solution would be
to have a `std::unique_ptr<SCEVUnionPredicate>` here, where a null
value means "always true" so that in the non-predicated case we only
use up one word.
The most compact solution (I think we should go with this) is to:
- Extract out a `struct ExitNotTakenExtras` that contains a
`SmallVector` of `ExitNotTaken` s and a `SCEVUnionPredicate`
- Change `PointerIntPair<ExitNotTakenInfo*, 1> NextExit` to
`PointerIntPair<ExitNotTakenExtras *, 1> NextExit` where it is
usually null, but if it is non-null you either have multiple exits
or have some SCEV predicates.
Normally I wouldn't worry so much about space, but `ExitNotTakenInfo`
has clearly been optimized for space usage, so we should try not to
break that.
================
Comment at: include/llvm/Analysis/ScalarEvolution.h:586
@@ -572,3 +585,3 @@
/// loop that is known, or a SCEVCouldNotCompute.
const SCEV *Max;
----------------
Add a comment here that `Max` is valid only if the predicates on each of the `ExitNotTakenInfo` instances is true.
================
Comment at: include/llvm/Analysis/ScalarEvolution.h:593
@@ -579,3 +592,3 @@
BackedgeTakenInfo(
- SmallVectorImpl< std::pair<BasicBlock *, const SCEV *> > &ExitCounts,
- bool Complete, const SCEV *MaxCount);
+ SmallVectorImpl<std::pair<BasicBlock *, const SCEV *>> &ExitCounts,
+ SmallVectorImpl<SCEVUnionPredicate *> &ExitPreds, bool Complete,
----------------
I think the right API here is to promote the `std::pair` into a full struct that carries the block, backedge count and a predicate; and not have a separate vector for `ExitPreds`. You could also use `std::tuple` here (since the types are all different, there isn't much scope for confusion).
================
Comment at: include/llvm/Analysis/ScalarEvolution.h:610
@@ +609,3 @@
+ /// loop if it is known and always correct (independent of any
+ /// assumptions that should be checked at run-time), or
+ /// SCEVCouldNotCompute otherwise. This is the number of times the loop
----------------
Can you please make this comment a little more clear? Is it that the caller needs to know in advance, by some other means, that the backedge taken count is predicated and pass in a non-null `Predicates`? If so, what is that other means?
The `always correct (independent of any assumptions that should be checked at run-time)` is misleading too -- you do sometimes return exact BE counts are **dependent** on a run-time assumption.
================
Comment at: include/llvm/Analysis/ScalarEvolution.h:639
@@ -614,1 +638,3 @@
DenseMap<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts;
+ /// Cache the predicated backedge-taken count of the loops for this
+ /// function as they are computed.
----------------
Here and elsewhere, can you please add a newline after field declarations (i.e. after the declaration for `BackedgeTakenCounts`)?
================
Comment at: include/llvm/Analysis/ScalarEvolution.h:750
@@ +749,3 @@
+ /// taken count will be known).
+ const BackedgeTakenInfo &getPredicatedBackedgeTakenInfo(const Loop *L);
+
----------------
I'd remove the `(the exact backedge taken count will be known)` bit -- it can otherwise mislead people into thinking that this will return a precise be count, no matter what.
================
Comment at: include/llvm/Analysis/ScalarEvolution.h:766
@@ -727,2 +765,3 @@
/// execute if its exit condition were a conditional branch of ExitCond,
- /// TBB, and FBB.
+ /// TBB, and FBB. If IsGuarded is set, this call try to use a minimal set
+ /// of SCEV predicates in order to return an exact answer.
----------------
Nit: the parameter name is `IsGuarded` and not `Guarded`. But, as I said earlier, it is probably better to rename this to `AddPredicates`, `AllowPredicates` or `CreatePredicates` as you have below.
================
Comment at: include/llvm/Analysis/ScalarEvolution.h:1227
@@ +1226,3 @@
+ const SCEV *getPredicatedBackedgeTakenCount(const Loop *L,
+ SCEVUnionPredicate &Predicates);
+
----------------
Nit: indentation.
================
Comment at: lib/Analysis/ScalarEvolution.cpp:5265
@@ +5264,3 @@
+ auto RemoveLoopFromBackedgeMap =
+ [L] (DenseMap<const Loop*, BackedgeTakenInfo> &Map) {
+ auto BTCPos = Map.find(L);
----------------
Usually I see lambdas formatted with no space between the `]` and the `(`. I'd say just run the diff through `clang-format` before checkin, and whatever it does is fine. :)
================
Comment at: lib/Analysis/ScalarEvolution.cpp:5273
@@ +5272,3 @@
+
+ RemoveLoopFromBackedgeMap(BackedgeTakenCounts);
+ RemoveLoopFromBackedgeMap(PredicatedBackedgeTakenCounts);
----------------
What you have here is fine, but I'd have tried:
```
for (auto &Map : {BackedgeTakenCounts, PredicatedBackedgeTakenCounts}) {
// Remove L from Map
}
```
(not 100% sure if the above will work).
================
Comment at: lib/Analysis/ScalarEvolution.cpp:5478
@@ -5426,3 +5477,3 @@
BasicBlock *ExitBB = ExitingBlocks[i];
- ExitLimit EL = computeExitLimit(L, ExitBB);
+ ExitLimit EL = computeExitLimit(L, ExitBB, Guarded);
----------------
Add an assert here that if `Guarded` is false, then the predicate in `EL` is trivially true (i.e. we didn't add a predicate when we were not supposed to).
================
Comment at: lib/Analysis/ScalarEvolution.cpp:5488
@@ -5436,1 +5487,3 @@
ExitCounts.push_back({ExitBB, EL.Exact});
+ ExitCountPreds.push_back(&EL.Pred);
+ }
----------------
This does not look right to me -- won't the `EL` be freed after each iteration, leaving a dangling pointer in `ExitCountPreds`?
http://reviews.llvm.org/D17201
More information about the llvm-commits
mailing list