+//===----------------------------------------------------------------------===//
+// LVIQuery Impl
+//===----------------------------------------------------------------------===//
+
+namespace {
+ /// LVIQuery - This is a transient object that exists while a query is
+ /// being performed.
+ ///
+ /// TODO: Reuse LVIQuery instead of recreating it for every query, this avoids
+ /// reallocation of the densemap on every query.
+ class LVIQuery {
+ typedef LazyValueInfoCache::BlockCacheEntryTy BlockCacheEntryTy;
+ typedef LazyValueInfoCache::ValueCacheEntryTy ValueCacheEntryTy;
+
+ /// This is the current value being queried for.
+ Value *Val;
+
+ /// This is a pointer to the owning cache, for recursive queries.
+ LazyValueInfoCache &Parent;
+
+ /// This is all of the cached information about this value.
+ ValueCacheEntryTy &Cache;
+
+ /// This tracks, for each block, what values are overdefined.
+ std::set<std::pair<AssertingVH<BasicBlock>, Value*> > &OverDefinedCache;
+
+ /// NewBlocks - This is a mapping of the new BasicBlocks which have been
+ /// added to cache but that are not in sorted order.
+ DenseSet<BasicBlock*> NewBlockInfo;
+
+ public:
+
+ LVIQuery(Value *V, LazyValueInfoCache &P,
+ ValueCacheEntryTy &VC,
+ std::set<std::pair<AssertingVH<BasicBlock>, Value*> > &ODC)
+ : Val(V), Parent(P), Cache(VC), OverDefinedCache(ODC) {
+ }
+
+ ~LVIQuery() {
+ // When the query is done, insert the newly discovered facts into the
+ // cache in sorted order.
+ if (NewBlockInfo.empty()) return;
+
+ for (DenseSet<BasicBlock*>::iterator I = NewBlockInfo.begin(),
+ E = NewBlockInfo.end(); I != E; ++I) {
+ if (Cache[*I].isOverdefined())
+ OverDefinedCache.insert(std::make_pair(*I, Val));
+ }
+ }
+
+ LVILatticeVal getBlockValue(BasicBlock *BB);
+ LVILatticeVal getEdgeValue(BasicBlock *FromBB, BasicBlock *ToBB);
+
+ private:
+ LVILatticeVal getCachedEntryForBlock(BasicBlock *BB);
+ };
+} // end anonymous namespace
+
+void LazyValueInfoCache::LVIValueHandle::deleted() {
+ for (std::set<std::pair<AssertingVH<BasicBlock>, Value*> >::iterator
+ I = Parent->OverDefinedCache.begin(),
+ E = Parent->OverDefinedCache.end();
+ I != E; ) {
+ std::set<std::pair<AssertingVH<BasicBlock>, Value*> >::iterator tmp = I;
+ ++I;
+ if (tmp->second == getValPtr())
+ Parent->OverDefinedCache.erase(tmp);
+ }
+
+ // This erasure deallocates *this, so it MUST happen after we're done
+ // using any and all members of *this.
+ Parent->ValueCache.erase(*this);
+}
+
+void LazyValueInfoCache::eraseBlock(BasicBlock *BB) {
+ for (std::set<std::pair<AssertingVH<BasicBlock>, Value*> >::iterator
+ I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E; ) {
+ std::set<std::pair<AssertingVH<BasicBlock>, Value*> >::iterator tmp = I;
+ ++I;
+ if (tmp->first == BB)
+ OverDefinedCache.erase(tmp);
+ }
+
+ for (std::map<LVIValueHandle, ValueCacheEntryTy>::iterator
+ I = ValueCache.begin(), E = ValueCache.end(); I != E; ++I)
+ I->second.erase(BB);
+}