diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index 7fef6289209..1566c5e6dcd 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -204,7 +204,7 @@ namespace { /// LazyValueInfoCache - This is the cache kept by LazyValueInfo which /// maintains information about queries across the clients' queries. class LazyValueInfoCache { - public: + private: /// BlockCacheEntryTy - This is a computed lattice value at the end of the /// specified basic block for a Value* that depends on context. typedef std::pair BlockCacheEntryTy; @@ -214,7 +214,6 @@ namespace { /// entries, allowing us to do a lookup with a binary search. typedef DenseMap ValueCacheEntryTy; - private: /// ValueCache - This is all of the cached information for all values, /// mapped from Value* to key information. DenseMap ValueCache; @@ -223,7 +222,54 @@ namespace { /// values that are over-defined at the end of that block. This is required /// for cache updating. DenseSet > OverDefinedCache; + + LVILatticeVal getBlockValue(ValueCacheEntryTy &Cache, BasicBlock *BB); + LVILatticeVal getEdgeValue(ValueCacheEntryTy &Cache, + BasicBlock *Pred, BasicBlock *Succ); + LVILatticeVal &getCachedEntryForBlock(ValueCacheEntryTy &Cache, + BasicBlock *BB); + + /************* Begin Per-Query State *************/ + /// This is the current value being queried for. + Value *Val; + + /// This is all of the cached information about this value. + //ValueCacheEntryTy *Cache; + + /// NewBlocks - This is a mapping of the new BasicBlocks which have been + /// added to cache but that are not in sorted order. + DenseSet NewBlockInfo; + + /// QuerySetup - An RAII helper to construct and tear-down per-query + /// temporary state. + struct QuerySetup { + LazyValueInfoCache &Owner; + QuerySetup(LazyValueInfoCache &O, Value* Val) : Owner(O) { + assert(!Owner.Val && "Per-query info not cleared?"); + Owner.Val = Val; + assert(Owner.NewBlockInfo.empty() && "Leaked block info!"); + } + + ~QuerySetup() { + // When the query is done, insert the newly discovered facts into the + // cache in sorted order. + LazyValueInfoCache::ValueCacheEntryTy Cache = + Owner.ValueCache[Owner.Val]; + for (DenseSet::iterator I = Owner.NewBlockInfo.begin(), + E = Owner.NewBlockInfo.end(); I != E; ++I) { + if (Cache[*I].isOverdefined()) + Owner.OverDefinedCache.insert(std::make_pair(*I, Owner.Val)); + } + + // Reset Per-Query State + Owner.Val = 0; + Owner.NewBlockInfo.clear(); + } + }; + /************* End Per-Query State *************/ + public: + LazyValueInfoCache() : Val(0) { } /// getValueInBlock - This is the query interface to determine the lattice /// value for the specified Value* at the end of the specified block. @@ -240,90 +286,20 @@ namespace { }; } // end anonymous namespace -namespace { - struct BlockCacheEntryComparator { - static int Compare(const void *LHSv, const void *RHSv) { - const LazyValueInfoCache::BlockCacheEntryTy *LHS = - static_cast(LHSv); - const LazyValueInfoCache::BlockCacheEntryTy *RHS = - static_cast(RHSv); - if (LHS->first < RHS->first) - return -1; - if (LHS->first > RHS->first) - return 1; - return 0; - } - - bool operator()(const LazyValueInfoCache::BlockCacheEntryTy &LHS, - const LazyValueInfoCache::BlockCacheEntryTy &RHS) const { - return LHS.first < RHS.first; - } - }; -} - -//===----------------------------------------------------------------------===// -// 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 all of the cached information about this value. - ValueCacheEntryTy &Cache; - - /// This tracks, for each block, what values are overdefined. - DenseSet > &OverDefinedCache; - - /// NewBlocks - This is a mapping of the new BasicBlocks which have been - /// added to cache but that are not in sorted order. - DenseSet NewBlockInfo; - public: - - LVIQuery(Value *V, ValueCacheEntryTy &VC, - DenseSet > &ODC) - : Val(V), 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::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 /// getCachedEntryForBlock - See if we already have a value for this block. If /// so, return it, otherwise create a new entry in the Cache map to use. -LVILatticeVal &LVIQuery::getCachedEntryForBlock(BasicBlock *BB) { +LVILatticeVal& +LazyValueInfoCache::getCachedEntryForBlock(ValueCacheEntryTy &Cache, + BasicBlock *BB) { NewBlockInfo.insert(BB); return Cache[BB]; } -LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) { +LVILatticeVal +LazyValueInfoCache::getBlockValue(ValueCacheEntryTy &Cache, BasicBlock *BB) { // See if we already have a value for this block. - LVILatticeVal &BBLV = getCachedEntryForBlock(BB); + LVILatticeVal &BBLV = getCachedEntryForBlock(Cache, BB); // If we've already computed this block's value, return it. if (!BBLV.isUndefined()) { @@ -345,7 +321,7 @@ LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) { // Loop over all of our predecessors, merging what we know from them into // result. for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { - Result.mergeIn(getEdgeValue(*PI, BB)); + Result.mergeIn(getEdgeValue(Cache, *PI, BB)); // If we hit overdefined, exit early. The BlockVals entry is already set // to overdefined. @@ -367,7 +343,7 @@ LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) { // Return the merged value, which is more precise than 'overdefined'. assert(!Result.isOverdefined()); - return getCachedEntryForBlock(BB) = Result; + return getCachedEntryForBlock(Cache, BB) = Result; } // If this value is defined by an instruction in this block, we have to @@ -384,12 +360,13 @@ LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) { LVILatticeVal Result; Result.markOverdefined(); - return getCachedEntryForBlock(BB) = Result; + return getCachedEntryForBlock(Cache, BB) = Result; } /// getEdgeValue - This method attempts to infer more complex -LVILatticeVal LVIQuery::getEdgeValue(BasicBlock *BBFrom, BasicBlock *BBTo) { +LVILatticeVal LazyValueInfoCache::getEdgeValue(ValueCacheEntryTy &Cache, + BasicBlock *BBFrom, BasicBlock *BBTo) { // TODO: Handle more complex conditionals. If (v == 0 || v2 < 1) is false, we // know that v != 0. if (BranchInst *BI = dyn_cast(BBFrom->getTerminator())) { @@ -443,14 +420,9 @@ LVILatticeVal LVIQuery::getEdgeValue(BasicBlock *BBFrom, BasicBlock *BBTo) { } // Otherwise see if the value is known in the block. - return getBlockValue(BBFrom); + return getBlockValue(Cache, BBFrom); } - -//===----------------------------------------------------------------------===// -// LazyValueInfoCache Impl -//===----------------------------------------------------------------------===// - LVILatticeVal LazyValueInfoCache::getValueInBlock(Value *V, BasicBlock *BB) { // If already a constant, there is nothing to compute. if (Constant *VC = dyn_cast(V)) @@ -459,8 +431,9 @@ LVILatticeVal LazyValueInfoCache::getValueInBlock(Value *V, BasicBlock *BB) { DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '" << BB->getName() << "'\n"); - LVILatticeVal Result = LVIQuery(V, ValueCache[V], - OverDefinedCache).getBlockValue(BB); + QuerySetup QS(*this, V); + ValueCacheEntryTy &Cache = ValueCache[V]; + LVILatticeVal Result = getBlockValue(Cache, BB); DEBUG(dbgs() << " Result = " << Result << "\n"); return Result; @@ -475,9 +448,9 @@ getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB) { DEBUG(dbgs() << "LVI Getting edge value " << *V << " from '" << FromBB->getName() << "' to '" << ToBB->getName() << "'\n"); - LVILatticeVal Result = - LVIQuery(V, ValueCache[V], - OverDefinedCache).getEdgeValue(FromBB, ToBB); + QuerySetup QS(*this, V); + ValueCacheEntryTy &Cache = ValueCache[V]; + LVILatticeVal Result = getEdgeValue(Cache, FromBB, ToBB); DEBUG(dbgs() << " Result = " << Result << "\n");