diff options
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
| -rw-r--r-- | llvm/lib/Analysis/LazyValueInfo.cpp | 201 |
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. |
