From: Owen Anderson Date: Tue, 27 Jul 2010 23:58:11 +0000 (+0000) Subject: Rearrange several datastructures in LazyValueInfo to improve compile time. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=9a65dc996801d73c2a460a41cdb46bff6f8303a1;p=oota-llvm.git Rearrange several datastructures in LazyValueInfo to improve compile time. This is still not perfect, but better than it was before. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109563 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index a72faca6847..7fef6289209 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -22,6 +22,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/STLExtras.h" using namespace llvm; @@ -211,7 +212,7 @@ namespace { /// ValueCacheEntryTy - This is all of the cached block information for /// exactly one Value*. The entries are sorted by the BasicBlock* of the /// entries, allowing us to do a lookup with a binary search. - typedef std::vector ValueCacheEntryTy; + typedef DenseMap ValueCacheEntryTy; private: /// ValueCache - This is all of the cached information for all values, @@ -221,7 +222,7 @@ namespace { /// OverDefinedCache - This tracks, on a per-block basis, the set of /// values that are over-defined at the end of that block. This is required /// for cache updating. - DenseMap > OverDefinedCache; + DenseSet > OverDefinedCache; public: /// getValueInBlock - This is the query interface to determine the lattice @@ -281,15 +282,15 @@ namespace { ValueCacheEntryTy &Cache; /// This tracks, for each block, what values are overdefined. - DenseMap > &OverDefinedCache; + DenseSet > &OverDefinedCache; /// NewBlocks - This is a mapping of the new BasicBlocks which have been /// added to cache but that are not in sorted order. - DenseMap NewBlockInfo; + DenseSet NewBlockInfo; public: LVIQuery(Value *V, ValueCacheEntryTy &VC, - DenseMap > &ODC) + DenseSet > &ODC) : Val(V), Cache(VC), OverDefinedCache(ODC) { } @@ -297,34 +298,11 @@ namespace { // When the query is done, insert the newly discovered facts into the // cache in sorted order. if (NewBlockInfo.empty()) return; - - // Grow the cache to exactly fit the new data. - Cache.reserve(Cache.size() + NewBlockInfo.size()); - // If we only have one new entry, insert it instead of doing a full-on - // sort. - if (NewBlockInfo.size() == 1) { - BlockCacheEntryTy Entry = *NewBlockInfo.begin(); - ValueCacheEntryTy::iterator I = - std::lower_bound(Cache.begin(), Cache.end(), Entry, - BlockCacheEntryComparator()); - assert((I == Cache.end() || I->first != Entry.first) && - "Entry already in map!"); - - Cache.insert(I, Entry); - return; - } - - // TODO: If we only have two new elements, INSERT them both. - - Cache.insert(Cache.end(), NewBlockInfo.begin(), NewBlockInfo.end()); - array_pod_sort(Cache.begin(), Cache.end(), - BlockCacheEntryComparator::Compare); - - for (DenseMap::iterator - I = NewBlockInfo.begin(), E = NewBlockInfo.end(); I != E; ++I) { - if (I->second.isOverdefined()) - OverDefinedCache[I->first].insert(Val); + for (DenseSet::iterator I = NewBlockInfo.begin(), + E = NewBlockInfo.end(); I != E; ++I) { + if (Cache[*I].isOverdefined()) + OverDefinedCache.insert(std::make_pair(*I, Val)); } } @@ -337,23 +315,10 @@ namespace { } // 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 NewBlockInfo map to use. +/// so, return it, otherwise create a new entry in the Cache map to use. LVILatticeVal &LVIQuery::getCachedEntryForBlock(BasicBlock *BB) { - - // Do a binary search to see if we already have an entry for this block in - // the cache set. If so, find it. - if (!Cache.empty()) { - ValueCacheEntryTy::iterator Entry = - std::lower_bound(Cache.begin(), Cache.end(), - BlockCacheEntryTy(BB, LVILatticeVal()), - BlockCacheEntryComparator()); - if (Entry != Cache.end() && Entry->first == BB) - return Entry->second; - } - - // Otherwise, check to see if it's in NewBlockInfo or create a new entry if - // not. - return NewBlockInfo[BB]; + NewBlockInfo.insert(BB); + return Cache[BB]; } LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) { @@ -534,9 +499,12 @@ void LazyValueInfoCache::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, std::vector worklist; worklist.push_back(OldSucc); - std::set ClearSet = OverDefinedCache[OldSucc]; - LVILatticeVal OverDef; - OverDef.markOverdefined(); + DenseSet ClearSet; + for (DenseSet >::iterator + I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E; ++I) { + if (I->first == OldSucc) + ClearSet.insert(I->second); + } // Use a worklist to perform a depth-first search of OldSucc's successors. // NOTE: We do not need a visited list since any blocks we have already @@ -550,26 +518,24 @@ void LazyValueInfoCache::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, if (ToUpdate == NewSucc) continue; bool changed = false; - std::set &CurrentSet = OverDefinedCache[ToUpdate]; - for (std::set::iterator I = ClearSet.begin(),E = ClearSet.end(); + for (DenseSet::iterator I = ClearSet.begin(),E = ClearSet.end(); I != E; ++I) { // If a value was marked overdefined in OldSucc, and is here too... - if (CurrentSet.count(*I)) { - // Remove it from the caches. - ValueCacheEntryTy &Entry = ValueCache[*I]; - ValueCacheEntryTy::iterator CI = - std::lower_bound(Entry.begin(), Entry.end(), - std::make_pair(ToUpdate, OverDef), - BlockCacheEntryComparator()); - assert(CI != Entry.end() && "Couldn't find entry to update?"); - Entry.erase(CI); - - CurrentSet.erase(*I); - - // If we removed anything, then we potentially need to update - // blocks successors too. - changed = true; - } + DenseSet >::iterator OI = + OverDefinedCache.find(std::make_pair(ToUpdate, *I)); + if (OI == OverDefinedCache.end()) continue; + + // Remove it from the caches. + ValueCacheEntryTy &Entry = ValueCache[*I]; + ValueCacheEntryTy::iterator CI = Entry.find(ToUpdate); + + assert(CI != Entry.end() && "Couldn't find entry to update?"); + Entry.erase(CI); + OverDefinedCache.erase(OI); + + // If we removed anything, then we potentially need to update + // blocks successors too. + changed = true; } if (!changed) continue;