[llvm] r282375 - [SCEV] Combine two predicates into one; NFC
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 25 19:44:07 PDT 2016
Author: sanjoy
Date: Sun Sep 25 21:44:07 2016
New Revision: 282375
URL: http://llvm.org/viewvc/llvm-project?rev=282375&view=rev
Log:
[SCEV] Combine two predicates into one; NFC
Both `loopHasNoSideEffects` and `loopHasNoAbnormalExits` involve walking
the loop and maintaining similar sorts of caches. This commit changes
SCEV to compute both the predicates via a single walk, and maintain a
single cache instead of two.
Modified:
llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
llvm/trunk/lib/Analysis/ScalarEvolution.cpp
Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=282375&r1=282374&r2=282375&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Sun Sep 25 21:44:07 2016
@@ -725,22 +725,32 @@ private:
SmallVector<PointerIntPair<const Loop *, 2, LoopDisposition>, 2>>
LoopDispositions;
- /// Cache for \c loopHasNoAbnormalExits.
- DenseMap<const Loop *, bool> LoopHasNoAbnormalExits;
+ struct LoopProperties {
+ /// Set to true if the loop contains no instruction that can have side
+ /// effects (i.e. via throwing an exception, volatile or atomic access).
+ bool HasNoAbnormalExits;
- /// Cache for \c loopHasNoSideEffects.
- DenseMap<const Loop *, bool> LoopHasNoSideEffects;
+ /// Set to true if the loop contains no instruction that can abnormally exit
+ /// the loop (i.e. via throwing an exception, by terminating the thread
+ /// cleanly or by infinite looping in a called function). Strictly
+ /// speaking, the last one is not leaving the loop, but is identical to
+ /// leaving the loop for reasoning about undefined behavior.
+ bool HasNoSideEffects;
+ };
- /// Returns true if \p L contains no instruction that can have side effects
- /// (i.e. via throwing an exception, volatile or atomic access).
- bool loopHasNoSideEffects(const Loop *L);
-
- /// Returns true if \p L contains no instruction that can abnormally exit
- /// the loop (i.e. via throwing an exception, by terminating the thread
- /// cleanly or by infinite looping in a called function). Strictly
- /// speaking, the last one is not leaving the loop, but is identical to
- /// leaving the loop for reasoning about undefined behavior.
- bool loopHasNoAbnormalExits(const Loop *L);
+ /// Cache for \c getLoopProperties.
+ DenseMap<const Loop *, LoopProperties> LoopPropertiesCache;
+
+ /// Return a \c LoopProperties instance for \p L, creating one if necessary.
+ LoopProperties getLoopProperties(const Loop *L);
+
+ bool loopHasNoSideEffects(const Loop *L) {
+ return getLoopProperties(L).HasNoSideEffects;
+ }
+
+ bool loopHasNoAbnormalExits(const Loop *L) {
+ return getLoopProperties(L).HasNoAbnormalExits;
+ }
/// Compute a LoopDisposition value.
LoopDisposition computeLoopDisposition(const SCEV *S, const Loop *L);
Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=282375&r1=282374&r2=282375&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sun Sep 25 21:44:07 2016
@@ -4953,39 +4953,33 @@ bool ScalarEvolution::isAddRecNeverPoiso
return LatchControlDependentOnPoison && loopHasNoAbnormalExits(L);
}
-bool ScalarEvolution::loopHasNoSideEffects(const Loop *L) {
- auto Itr = LoopHasNoSideEffects.find(L);
- if (Itr == LoopHasNoSideEffects.end()) {
- auto NoSideEffectsInBB = [&](BasicBlock *BB) {
- return all_of(*BB, [](Instruction &I) {
- // Non-atomic, non-volatile stores are ok.
- if (auto *SI = dyn_cast<StoreInst>(&I))
- return SI->isSimple();
+ScalarEvolution::LoopProperties
+ScalarEvolution::getLoopProperties(const Loop *L) {
+ typedef ScalarEvolution::LoopProperties LoopProperties;
+
+ auto Itr = LoopPropertiesCache.find(L);
+ if (Itr == LoopPropertiesCache.end()) {
+ auto HasSideEffects = [](Instruction *I) {
+ if (auto *SI = dyn_cast<StoreInst>(I))
+ return !SI->isSimple();
- return !I.mayHaveSideEffects();
- });
+ return I->mayHaveSideEffects();
};
- auto InsertPair = LoopHasNoSideEffects.insert(
- {L, all_of(L->getBlocks(), NoSideEffectsInBB)});
- assert(InsertPair.second && "We just checked!");
- Itr = InsertPair.first;
- }
-
- return Itr->second;
-}
+ LoopProperties LP = {/* HasNoAbnormalExits */ true,
+ /*HasNoSideEffects*/ true};
-bool ScalarEvolution::loopHasNoAbnormalExits(const Loop *L) {
- auto Itr = LoopHasNoAbnormalExits.find(L);
- if (Itr == LoopHasNoAbnormalExits.end()) {
- auto NoAbnormalExitInBB = [&](BasicBlock *BB) {
- return all_of(*BB, [](Instruction &I) {
- return isGuaranteedToTransferExecutionToSuccessor(&I);
- });
- };
+ for (auto *BB : L->getBlocks())
+ for (auto &I : *BB) {
+ if (!isGuaranteedToTransferExecutionToSuccessor(&I))
+ LP.HasNoAbnormalExits = false;
+ if (HasSideEffects(&I))
+ LP.HasNoSideEffects = false;
+ if (!LP.HasNoAbnormalExits && !LP.HasNoSideEffects)
+ break; // We're already as pessimistic as we can get.
+ }
- auto InsertPair = LoopHasNoAbnormalExits.insert(
- {L, all_of(L->getBlocks(), NoAbnormalExitInBB)});
+ auto InsertPair = LoopPropertiesCache.insert({L, LP});
assert(InsertPair.second && "We just checked!");
Itr = InsertPair.first;
}
@@ -5561,8 +5555,7 @@ void ScalarEvolution::forgetLoop(const L
for (Loop *I : *L)
forgetLoop(I);
- LoopHasNoAbnormalExits.erase(L);
- LoopHasNoSideEffects.erase(L);
+ LoopPropertiesCache.erase(L);
}
void ScalarEvolution::forgetValue(Value *V) {
More information about the llvm-commits
mailing list