[cfe-commits] r60523 - /cfe/trunk/lib/Analysis/RegionStore.cpp
Zhongxing Xu
xuzhongxing at gmail.com
Wed Dec 3 18:17:37 PST 2008
Great!
On Thu, Dec 4, 2008 at 10:08 AM, Ted Kremenek <kremenek at apple.com> wrote:
> Author: kremenek
> Date: Wed Dec 3 20:08:27 2008
> New Revision: 60523
>
> URL: http://llvm.org/viewvc/llvm-project?rev=60523&view=rev
> Log:
> Revamp RegionStoreManager::RemoveDeadBindings. This method now does a
> complete mark-and-sweep of the store, removing dead regions and recording
> the set of live and dead symbols appropriately.
>
> Modified:
> cfe/trunk/lib/Analysis/RegionStore.cpp
>
> Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=60523&r1=60522&r2=60523&view=diff
>
>
> ==============================================================================
> --- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
> +++ cfe/trunk/lib/Analysis/RegionStore.cpp Wed Dec 3 20:08:27 2008
> @@ -52,6 +52,17 @@
> };
> }
>
> +// KillSet GDM stuff.
> +typedef llvm::ImmutableSet<const MemRegion*> RegionKillSetTy;
> +static int RegionKillSetTyIndex = 0;
> +namespace clang {
> + template<> struct GRStateTrait<RegionKillSetTy>
> + : public GRStatePartialTrait<RegionKillSetTy> {
> + static void* GDMIndex() { return &RegionKillSetTyIndex; }
> + };
> +}
> +
> +
> namespace {
>
> class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
> @@ -116,10 +127,15 @@
> assert (false && "Not implemented.");
> return 0;
> }
> -
> +
> + /// RemoveDeadBindings - Scans a RegionStore for dead values. It
> returns
> + /// a new Store with these values removed, and populates LSymbols and
> + /// DSymbols with the known set of live and dead symbols respectively.
> Store RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables&
> Live,
> llvm::SmallVectorImpl<const MemRegion*>&
> RegionRoots,
> LiveSymbolsTy& LSymbols, DeadSymbolsTy&
> DSymbols);
> +
> + void UpdateLiveSymbols(SVal X, LiveSymbolsTy& LSymbols);
>
> Store BindDecl(Store store, const VarDecl* VD, SVal* InitVal, unsigned
> Count);
>
> @@ -605,22 +621,130 @@
> }
>
>
> +void RegionStoreManager::UpdateLiveSymbols(SVal X, LiveSymbolsTy&
> LSymbols) {
> + for (SVal::symbol_iterator
> SI=X.symbol_begin(),SE=X.symbol_end();SI!=SE;++SI)
> + LSymbols.insert(*SI);
> +}
> +
> Store RegionStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
> const LiveVariables& Live,
> llvm::SmallVectorImpl<const MemRegion*>&
> RegionRoots,
> LiveSymbolsTy& LSymbols, DeadSymbolsTy&
> DSymbols) {
>
> RegionBindingsTy B = GetRegionBindings(store);
> - typedef SVal::symbol_iterator symbol_iterator;
> -
> - // FIXME: Mark all region binding value's symbol as live. We also omit
> symbols
> - // in SymbolicRegions.
> +
> + // Lazily constructed backmap from MemRegions to SubRegions.
> + typedef llvm::ImmutableSet<const MemRegion*> SubRegionsTy;
> + typedef llvm::ImmutableMap<const MemRegion*, SubRegionsTy>
> SubRegionsMapTy;
> +
> + // FIXME: As a future optimization we can modifiy BumpPtrAllocator to
> have
> + // the ability to reuse memory. This way we can keep TmpAlloc around as
> + // an instance variable of RegionStoreManager (avoiding repeated malloc
> + // overhead).
> + llvm::BumpPtrAllocator TmpAlloc;
> +
> + // Factory objects.
> + SubRegionsMapTy::Factory SubRegMapF(TmpAlloc);
> + SubRegionsTy::Factory SubRegF(TmpAlloc);
> +
> + // The backmap from regions to subregions.
> + SubRegionsMapTy SubRegMap = SubRegMapF.GetEmptyMap();
> +
> + // Do a pass over the regions in the store. For VarRegions we check if
> + // the variable is still live and if so add it to the list of live
> roots.
> + // For other regions we populate our region backmap.
> for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
> {
> - SVal X = I.getData();
> - for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE;
> ++SI)
> - LSymbols.insert(*SI);
> + const MemRegion* R = I.getKey();
> + if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
> + if (Live.isLive(Loc, VR->getDecl()))
> + RegionRoots.push_back(VR); // This is a live "root".
> + }
> + else {
> + // Get the super region for R.
> + const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion();
> + // Get the current set of subregions for SuperR.
> + const SubRegionsTy* SRptr = SubRegMap.lookup(SuperR);
> + SubRegionsTy SR = SRptr ? *SRptr : SubRegF.GetEmptySet();
> + // Add R to the subregions of SuperR.
> + SubRegMap = SubRegMapF.Add(SubRegMap, SuperR, SubRegF.Add(SR, R));
> +
> + // Finally, check if SuperR is a VarRegion. We need to do this
> + // to also mark SuperR as a root (as it may not have a value
> directly
> + // bound to it in the store).
> + if (const VarRegion* VR = dyn_cast<VarRegion>(SuperR)) {
> + if (Live.isLive(Loc, VR->getDecl()))
> + RegionRoots.push_back(VR); // This is a live "root".
> + }
> + }
> }
> +
> + // Process the worklist of RegionRoots. This performs a
> "mark-and-sweep"
> + // of the store. We want to find all live symbols and dead regions.
> + llvm::SmallPtrSet<const MemRegion*, 10> Marked;
> +
> + while (!RegionRoots.empty()) {
> + // Dequeue the next region on the worklist.
> + const MemRegion* R = RegionRoots.back();
> + RegionRoots.pop_back();
> +
> + // Check if we have already processed this region.
> + if (Marked.count(R)) continue;
> +
> + // Mark this region as processed. This is needed for termination in
> case
> + // a region is referenced more than once.
> + Marked.insert(R);
> +
> + // Mark the symbol for any live SymbolicRegion as "live". This means
> we
> + // should continue to track that symbol.
> + if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
> + LSymbols.insert(SymR->getSymbol());
> +
> + // Get the data binding for R (if any).
> + RegionBindingsTy::data_type* Xptr = B.lookup(R);
> + if (Xptr) {
> + SVal X = *Xptr;
> + UpdateLiveSymbols(X, LSymbols); // Update the set of live symbols.
> +
> + // If X is a region, then add it the RegionRoots.
> + if (loc::MemRegionVal* RegionX = dyn_cast<loc::MemRegionVal>(&X))
> + RegionRoots.push_back(RegionX->getRegion());
> + }
> +
> + // Get the subregions of R. These are RegionRoots as well since they
> + // represent values that are also bound to R.
> + const SubRegionsTy* SRptr = SubRegMap.lookup(R);
> + if (!SRptr) continue;
> + SubRegionsTy SR = *SRptr;
> +
> + for (SubRegionsTy::iterator I=SR.begin(), E=SR.end(); I!=E; ++I)
> + RegionRoots.push_back(*I);
> + }
> +
> + // We have now scanned the store, marking reachable regions and symbols
> + // as live. We now remove all the regions that are dead from the store
> + // as well as update DSymbols with the set symbols that are now dead.
> +
> + for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
> {
> + const MemRegion* R = I.getKey();
> +
> + // If this region live? Is so, none of its symbols are dead.
> + if (Marked.count(R))
> + continue;
> +
> + // Remove this dead region from the store.
> + store = Remove(store, loc::MemRegionVal(R));
>
> + // Mark all non-live symbols that this region references as dead.
> + if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R)) {
> + SymbolID Sym = SymR->getSymbol();
> + if (!LSymbols.count(Sym)) DSymbols.insert(Sym);
> + }
> +
> + SVal X = I.getData();
> + SVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
> + for (; SI != SE; ++SI) { if (!LSymbols.count(*SI))
> DSymbols.insert(*SI); }
> + }
> +
> return store;
> }
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20081204/870358e8/attachment.html>
More information about the cfe-commits
mailing list