зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
43ae4b0d2b
Коммит
77d7ef8d8a
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче