diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-04-24 18:31:42 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-04-24 18:31:42 +0000 |
commit | 77d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4 (patch) | |
tree | 04198313e050aa108bb02c1cc9a0ee191a8c0d2a | |
parent | 43ae4b0d2ba2a7de1c3ccb25f22955489999e1fb (diff) |
Added initial boilerplate in GRExprEngine to allow checker-specific transfer
function logic to act when symbols become dead.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50221 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 4 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/ValueState.h | 6 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 29 | ||||
-rw-r--r-- | lib/Analysis/ValueState.cpp | 30 |
4 files changed, 57 insertions, 12 deletions
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 2d088c788d..819043edb4 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -53,6 +53,10 @@ protected: /// Expr* in the CFG. Used to prune out dead state. LiveVariables Liveness; + /// DeadSymbols - A scratch set used to record the set of symbols that + /// were just marked dead by a call to ValueStateManager::RemoveDeadBindings. + ValueStateManager::DeadSymbolsTy DeadSymbols; + /// Builder - The current GRStmtNodeBuilder which is used when building the /// nodes for a given statement. StmtNodeBuilder* Builder; diff --git a/include/clang/Analysis/PathSensitive/ValueState.h b/include/clang/Analysis/PathSensitive/ValueState.h index 71e6abddba..5e287b23b0 100644 --- a/include/clang/Analysis/PathSensitive/ValueState.h +++ b/include/clang/Analysis/PathSensitive/ValueState.h @@ -30,6 +30,7 @@ #include "llvm/ADT/ImmutableMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Streams.h" @@ -222,8 +223,11 @@ public: BasicValueFactory& getBasicValueFactory() { return BasicVals; } SymbolManager& getSymbolManager() { return SymMgr; } + typedef llvm::DenseSet<SymbolID> DeadSymbolsTy; + ValueState* RemoveDeadBindings(ValueState* St, Stmt* Loc, - const LiveVariables& Liveness); + const LiveVariables& Liveness, + DeadSymbolsTy& DeadSymbols); ValueState* RemoveSubExprBindings(ValueState* St) { ValueState NewSt = *St; diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index a6d8ef9051..a287e54298 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -188,13 +188,34 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) { // Create the cleaned state. CleanedState = StateMgr.RemoveDeadBindings(StmtEntryNode->getState(), - CurrentStmt, Liveness); + CurrentStmt, Liveness, + DeadSymbols); - Builder->SetCleanedState(CleanedState); + // Process any special transfer function for dead symbols. - // Visit the statement. + NodeSet Tmp; - Visit(S, StmtEntryNode, Dst); + if (DeadSymbols.empty()) + Tmp.Add(StmtEntryNode); + else { + SaveAndRestore<bool> OldSink(Builder->BuildSinks); +/* + FIXME: Will hook this up next. + + TF->EvalDeadSymbols(Tmp, *this, *Builder, StmtEntryNode->getLocation(), Pred, + CleanedState, DeadSymbols); +*/ + if (!Builder->BuildSinks && Tmp.empty() && !Builder->HasGeneratedNode) + Tmp.Add(StmtEntryNode); + } + + for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { + // Set the cleaned state. + Builder->SetCleanedState(*I == StmtEntryNode ? CleanedState : (*I)->getState()); + + // Visit the statement. + Visit(S, StmtEntryNode, Dst); + } // If no nodes were generated, generate a new node that has all the // dead mappings removed. diff --git a/lib/Analysis/ValueState.cpp b/lib/Analysis/ValueState.cpp index 8027ce9fcb..ed6a86075b 100644 --- a/lib/Analysis/ValueState.cpp +++ b/lib/Analysis/ValueState.cpp @@ -32,7 +32,8 @@ const llvm::APSInt* ValueState::getSymVal(SymbolID sym) const { ValueState* ValueStateManager::RemoveDeadBindings(ValueState* St, Stmt* Loc, - const LiveVariables& Liveness) { + const LiveVariables& Liveness, + DeadSymbolsTy& DeadSymbols) { // This code essentially performs a "mark-and-sweep" of the VariableBindings. // The roots are any Block-level exprs and Decls that our liveness algorithm @@ -133,13 +134,28 @@ ValueStateManager::RemoveDeadBindings(ValueState* St, Stmt* Loc, NewSt.VarBindings = Remove(NewSt, I.getKey()); // Remove dead symbols. - for (ValueState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I) - if (!MarkedSymbols.count(I.getKey())) - NewSt.ConstEq = CEFactory.Remove(NewSt.ConstEq, I.getKey()); - for (ValueState::cne_iterator I = St->cne_begin(), E=St->cne_end(); I!=E; ++I) - if (!MarkedSymbols.count(I.getKey())) - NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, I.getKey()); + DeadSymbols.clear(); + + for (ValueState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I) { + + SymbolID sym = I.getKey(); + + if (!MarkedSymbols.count(sym)) { + DeadSymbols.insert(sym); + NewSt.ConstEq = CEFactory.Remove(NewSt.ConstEq, sym); + } + } + + for (ValueState::cne_iterator I = St->cne_begin(), E=St->cne_end(); I!=E;++I){ + + SymbolID sym = I.getKey(); + + if (!MarkedSymbols.count(sym)) { + DeadSymbols.insert(sym); + NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, sym); + } + } return getPersistentState(NewSt); } |