summaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp201
1 files changed, 98 insertions, 103 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 6cded828c25f..f10b2bc06746 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -60,8 +60,10 @@ INITIALIZE_PASS_END(LazyValueInfoWrapperPass, "lazy-value-info",
"Lazy Value Information Analysis", false, true)
namespace llvm {
- FunctionPass *createLazyValueInfoPass() { return new LazyValueInfoWrapperPass(); }
+FunctionPass *createLazyValueInfoPass() {
+ return new LazyValueInfoWrapperPass();
}
+} // namespace llvm
AnalysisKey LazyValueAnalysis::Key;
@@ -151,114 +153,113 @@ namespace {
} // end anonymous namespace
namespace {
- using NonNullPointerSet = SmallDenseSet<AssertingVH<Value>, 2>;
-
- /// This is the cache kept by LazyValueInfo which
- /// maintains information about queries across the clients' queries.
- class LazyValueInfoCache {
- /// This is all of the cached information for one basic block. It contains
- /// the per-value lattice elements, as well as a separate set for
- /// overdefined values to reduce memory usage. Additionally pointers
- /// dereferenced in the block are cached for nullability queries.
- struct BlockCacheEntry {
- SmallDenseMap<AssertingVH<Value>, ValueLatticeElement, 4> LatticeElements;
- SmallDenseSet<AssertingVH<Value>, 4> OverDefined;
- // std::nullopt indicates that the nonnull pointers for this basic block
- // block have not been computed yet.
- std::optional<NonNullPointerSet> NonNullPointers;
- };
-
- /// Cached information per basic block.
- DenseMap<PoisoningVH<BasicBlock>, std::unique_ptr<BlockCacheEntry>>
- BlockCache;
- /// Set of value handles used to erase values from the cache on deletion.
- DenseSet<LVIValueHandle, DenseMapInfo<Value *>> ValueHandles;
-
- const BlockCacheEntry *getBlockEntry(BasicBlock *BB) const {
- auto It = BlockCache.find_as(BB);
- if (It == BlockCache.end())
- return nullptr;
- return It->second.get();
- }
+using NonNullPointerSet = SmallDenseSet<AssertingVH<Value>, 2>;
+
+/// This is the cache kept by LazyValueInfo which
+/// maintains information about queries across the clients' queries.
+class LazyValueInfoCache {
+ /// This is all of the cached information for one basic block. It contains
+ /// the per-value lattice elements, as well as a separate set for
+ /// overdefined values to reduce memory usage. Additionally pointers
+ /// dereferenced in the block are cached for nullability queries.
+ struct BlockCacheEntry {
+ SmallDenseMap<AssertingVH<Value>, ValueLatticeElement, 4> LatticeElements;
+ SmallDenseSet<AssertingVH<Value>, 4> OverDefined;
+ // std::nullopt indicates that the nonnull pointers for this basic block
+ // block have not been computed yet.
+ std::optional<NonNullPointerSet> NonNullPointers;
+ };
- BlockCacheEntry *getOrCreateBlockEntry(BasicBlock *BB) {
- auto It = BlockCache.find_as(BB);
- if (It == BlockCache.end())
- It = BlockCache.insert({ BB, std::make_unique<BlockCacheEntry>() })
- .first;
+ /// Cached information per basic block.
+ DenseMap<PoisoningVH<BasicBlock>, std::unique_ptr<BlockCacheEntry>>
+ BlockCache;
+ /// Set of value handles used to erase values from the cache on deletion.
+ DenseSet<LVIValueHandle, DenseMapInfo<Value *>> ValueHandles;
+
+ const BlockCacheEntry *getBlockEntry(BasicBlock *BB) const {
+ auto It = BlockCache.find_as(BB);
+ if (It == BlockCache.end())
+ return nullptr;
+ return It->second.get();
+ }
- return It->second.get();
- }
+ BlockCacheEntry *getOrCreateBlockEntry(BasicBlock *BB) {
+ auto It = BlockCache.find_as(BB);
+ if (It == BlockCache.end())
+ It = BlockCache.insert({BB, std::make_unique<BlockCacheEntry>()}).first;
- void addValueHandle(Value *Val) {
- auto HandleIt = ValueHandles.find_as(Val);
- if (HandleIt == ValueHandles.end())
- ValueHandles.insert({ Val, this });
- }
+ return It->second.get();
+ }
- public:
- void insertResult(Value *Val, BasicBlock *BB,
- const ValueLatticeElement &Result) {
- BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
+ void addValueHandle(Value *Val) {
+ auto HandleIt = ValueHandles.find_as(Val);
+ if (HandleIt == ValueHandles.end())
+ ValueHandles.insert({Val, this});
+ }
- // Insert over-defined values into their own cache to reduce memory
- // overhead.
- if (Result.isOverdefined())
- Entry->OverDefined.insert(Val);
- else
- Entry->LatticeElements.insert({ Val, Result });
+public:
+ void insertResult(Value *Val, BasicBlock *BB,
+ const ValueLatticeElement &Result) {
+ BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
+
+ // Insert over-defined values into their own cache to reduce memory
+ // overhead.
+ if (Result.isOverdefined())
+ Entry->OverDefined.insert(Val);
+ else
+ Entry->LatticeElements.insert({Val, Result});
+
+ addValueHandle(Val);
+ }
- addValueHandle(Val);
- }
+ std::optional<ValueLatticeElement> getCachedValueInfo(Value *V,
+ BasicBlock *BB) const {
+ const BlockCacheEntry *Entry = getBlockEntry(BB);
+ if (!Entry)
+ return std::nullopt;
- std::optional<ValueLatticeElement>
- getCachedValueInfo(Value *V, BasicBlock *BB) const {
- const BlockCacheEntry *Entry = getBlockEntry(BB);
- if (!Entry)
- return std::nullopt;
+ if (Entry->OverDefined.count(V))
+ return ValueLatticeElement::getOverdefined();
- if (Entry->OverDefined.count(V))
- return ValueLatticeElement::getOverdefined();
+ auto LatticeIt = Entry->LatticeElements.find_as(V);
+ if (LatticeIt == Entry->LatticeElements.end())
+ return std::nullopt;
- auto LatticeIt = Entry->LatticeElements.find_as(V);
- if (LatticeIt == Entry->LatticeElements.end())
- return std::nullopt;
+ return LatticeIt->second;
+ }
- return LatticeIt->second;
+ bool
+ isNonNullAtEndOfBlock(Value *V, BasicBlock *BB,
+ function_ref<NonNullPointerSet(BasicBlock *)> InitFn) {
+ BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
+ if (!Entry->NonNullPointers) {
+ Entry->NonNullPointers = InitFn(BB);
+ for (Value *V : *Entry->NonNullPointers)
+ addValueHandle(V);
}
- bool isNonNullAtEndOfBlock(
- Value *V, BasicBlock *BB,
- function_ref<NonNullPointerSet(BasicBlock *)> InitFn) {
- BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
- if (!Entry->NonNullPointers) {
- Entry->NonNullPointers = InitFn(BB);
- for (Value *V : *Entry->NonNullPointers)
- addValueHandle(V);
- }
-
- return Entry->NonNullPointers->count(V);
- }
+ return Entry->NonNullPointers->count(V);
+ }
- /// clear - Empty the cache.
- void clear() {
- BlockCache.clear();
- ValueHandles.clear();
- }
+ /// clear - Empty the cache.
+ void clear() {
+ BlockCache.clear();
+ ValueHandles.clear();
+ }
- /// Inform the cache that a given value has been deleted.
- void eraseValue(Value *V);
+ /// Inform the cache that a given value has been deleted.
+ void eraseValue(Value *V);
- /// This is part of the update interface to inform the cache
- /// that a block has been deleted.
- void eraseBlock(BasicBlock *BB);
+ /// This is part of the update interface to inform the cache
+ /// that a block has been deleted.
+ void eraseBlock(BasicBlock *BB);
- /// Updates the cache to remove any influence an overdefined value in
- /// OldSucc might have (unless also overdefined in NewSucc). This just
- /// flushes elements from the cache and does not add any.
- void threadEdgeImpl(BasicBlock *OldSucc,BasicBlock *NewSucc);
- };
-}
+ /// Updates the cache to remove any influence an overdefined value in
+ /// OldSucc might have (unless also overdefined in NewSucc). This just
+ /// flushes elements from the cache and does not add any.
+ void threadEdgeImpl(BasicBlock *OldSucc, BasicBlock *NewSucc);
+};
+} // namespace
void LazyValueInfoCache::eraseValue(Value *V) {
for (auto &Pair : BlockCache) {
@@ -1116,9 +1117,6 @@ LazyValueInfoImpl::getValueFromSimpleICmpCondition(CmpInst::Predicate Pred,
if (!R)
return std::nullopt;
RHSRange = toConstantRange(*R, RHS->getType());
- } else if (Instruction *I = dyn_cast<Instruction>(RHS)) {
- if (auto *Ranges = I->getMetadata(LLVMContext::MD_range))
- RHSRange = getConstantRangeFromMetadata(*Ranges);
}
ConstantRange TrueValues =
@@ -1191,13 +1189,10 @@ std::optional<ValueLatticeElement> LazyValueInfoImpl::getValueFromICmpCondition(
return ValueLatticeElement::getRange(
ConstantRange::fromKnownBits(Known, /*IsSigned*/ false));
}
- // If (Val & Mask) != 0 then the value must be larger than the lowest set
- // bit of Mask.
- if (EdgePred == ICmpInst::ICMP_NE && !Mask->isZero() && C->isZero()) {
- return ValueLatticeElement::getRange(ConstantRange::getNonEmpty(
- APInt::getOneBitSet(BitWidth, Mask->countr_zero()),
- APInt::getZero(BitWidth)));
- }
+
+ if (EdgePred == ICmpInst::ICMP_NE)
+ return ValueLatticeElement::getRange(
+ ConstantRange::makeMaskNotEqualRange(*Mask, *C));
}
// If (X urem Modulus) >= C, then X >= C.