From: Ted Kremenek Date: Fri, 8 Feb 2008 19:17:19 +0000 (+0000) Subject: Moved implementation of "RemoveDeadBindings" from the main X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b87d9096d0bbce83fd5f79f2346dc49d1046e092;p=clang Moved implementation of "RemoveDeadBindings" from the main GRConstants logic to ValueStateManager. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46888 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp index 75edb911e6..8a06b725b9 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -192,11 +192,13 @@ public: /// nodes by processing the 'effects' of a branch condition. void ProcessBranch(Expr* Condition, Stmt* Term, BranchNodeBuilder& builder); - /// RemoveDeadBindings - Return a new state that is the same as 'M' except + /// RemoveDeadBindings - Return a new state that is the same as 'St' except /// that all subexpression mappings are removed and that any /// block-level expressions that are not live at 'S' also have their /// mappings removed. - StateTy RemoveDeadBindings(Stmt* S, StateTy M); + inline StateTy RemoveDeadBindings(Stmt* S, StateTy St) { + return StateMgr.RemoveDeadBindings(St, S, Liveness); + } StateTy SetValue(StateTy St, Stmt* S, const RValue& V); @@ -509,76 +511,6 @@ void GRConstants::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) { Builder = NULL; } -GRConstants::StateTy GRConstants::RemoveDeadBindings(Stmt* Loc, StateTy M) { - - // This code essentially performs a "mark-and-sweep" of the VariableBindings. - // The roots are any Block-level exprs and Decls that our liveness algorithm - // tells us are live. We then see what Decls they may reference, and keep - // those around. This code more than likely can be made faster, and the - // frequency of which this method is called should be experimented with - // for optimum performance. - - llvm::SmallVector WList; - - for (StateTy::vb_iterator I = M.begin(), E = M.end(); I!=E ; ++I) { - - // Remove old bindings for subexpressions. - if (I.getKey().isSubExpr()) { - M = StateMgr.Remove(M, I.getKey()); - continue; - } - - if (I.getKey().isBlkExpr()) { - if (Liveness.isLive(Loc, cast(I.getKey()))) { - if (isa(I.getData())) { - lval::DeclVal LV = cast(I.getData()); - WList.push_back(LV.getDecl()); - } - } - else - M = StateMgr.Remove(M, I.getKey()); - - continue; - } - - assert (I.getKey().isDecl()); - - if (VarDecl* V = dyn_cast(cast(I.getKey()))) - if (Liveness.isLive(Loc, V)) - WList.push_back(V); - } - - llvm::SmallPtrSet Marked; - - while (!WList.empty()) { - ValueDecl* V = WList.back(); - WList.pop_back(); - - if (Marked.count(V)) - continue; - - Marked.insert(V); - - if (V->getType()->isPointerType()) { - const LValue& LV = cast(GetValue(M, lval::DeclVal(V))); - - if (!isa(LV)) - continue; - - const lval::DeclVal& LVD = cast(LV); - WList.push_back(LVD.getDecl()); - } - } - - for (StateTy::vb_iterator I = M.begin(), E = M.end(); I!=E ; ++I) - if (I.getKey().isDecl()) - if (VarDecl* V = dyn_cast(cast(I.getKey()))) - if (!Marked.count(V)) - M = StateMgr.Remove(M, V); - - return M; -} - GRConstants::NodeTy* GRConstants::Nodify(NodeSet& Dst, Stmt* S, NodeTy* Pred, StateTy St) { diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp index d191623dd8..55451a959e 100644 --- a/Analysis/ValueState.cpp +++ b/Analysis/ValueState.cpp @@ -31,6 +31,77 @@ const llvm::APSInt* ValueState::getSymVal(SymbolID sym) const { return T ? T->getValue().second : NULL; } +ValueState +ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc, + const LiveVariables& Liveness) { + + // This code essentially performs a "mark-and-sweep" of the VariableBindings. + // The roots are any Block-level exprs and Decls that our liveness algorithm + // tells us are live. We then see what Decls they may reference, and keep + // those around. This code more than likely can be made faster, and the + // frequency of which this method is called should be experimented with + // for optimum performance. + + llvm::SmallVector WList; + + for (StateTy::vb_iterator I = St.begin(), E = St.end(); I!=E ; ++I) { + + // Remove old bindings for subexpressions. + if (I.getKey().isSubExpr()) { + St = Remove(St, I.getKey()); + continue; + } + + if (I.getKey().isBlkExpr()) { + if (Liveness.isLive(Loc, cast(I.getKey()))) { + if (isa(I.getData())) { + lval::DeclVal LV = cast(I.getData()); + WList.push_back(LV.getDecl()); + } + } + else + St = Remove(St, I.getKey()); + + continue; + } + + assert (I.getKey().isDecl()); + + if (VarDecl* V = dyn_cast(cast(I.getKey()))) + if (Liveness.isLive(Loc, V)) + WList.push_back(V); + } + + llvm::SmallPtrSet Marked; + + while (!WList.empty()) { + ValueDecl* V = WList.back(); + WList.pop_back(); + + if (Marked.count(V)) + continue; + + Marked.insert(V); + + if (V->getType()->isPointerType()) { + const LValue& LV = cast(GetValue(St, lval::DeclVal(V))); + + if (!isa(LV)) + continue; + + const lval::DeclVal& LVD = cast(LV); + WList.push_back(LVD.getDecl()); + } + } + + for (StateTy::vb_iterator I = St.begin(), E = St.end(); I!=E ; ++I) + if (I.getKey().isDecl()) + if (VarDecl* V = dyn_cast(cast(I.getKey()))) + if (!Marked.count(V)) + St = Remove(St, V); + + return St; +} RValue ValueStateManager::GetValue(const StateTy& St, const LValue& LV, diff --git a/Analysis/ValueState.h b/Analysis/ValueState.h index 4de4f2e3f9..f431d1e441 100644 --- a/Analysis/ValueState.h +++ b/Analysis/ValueState.h @@ -241,13 +241,18 @@ public: ValueManager& getValueManager() { return ValMgr; } SymbolManager& getSymbolManager() { return SymMgr; } + StateTy RemoveDeadBindings(StateTy St, Stmt* Loc, + const LiveVariables& Liveness); + StateTy SetValue(StateTy St, Stmt* S, bool isBlkExpr, const RValue& V); StateTy SetValue(StateTy St, const LValue& LV, const RValue& V); RValue GetValue(const StateTy& St, Stmt* S, bool* hasVal = NULL); - RValue GetValue(const StateTy& St, const LValue& LV, QualType* T = NULL); - + RValue GetValue(const StateTy& St, const LValue& LV, QualType* T = NULL); LValue GetLValue(const StateTy& St, Stmt* S); + + + StateTy Add(StateTy St, VarBindKey K, const RValue& V); StateTy Remove(StateTy St, VarBindKey K);