More boilerplate for handling specialized-transfer function logic for dead symbols.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50233 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index a287e54..0438059 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -42,7 +42,7 @@
BasicVals(StateMgr.getBasicValueFactory()),
TF(NULL), // FIXME
SymMgr(StateMgr.getSymbolManager()),
- StmtEntryNode(NULL), CleanedState(NULL), CurrentStmt(NULL) {
+ CurrentStmt(NULL) {
// Compute liveness information.
Liveness.runOnCFG(G.getCFG());
@@ -167,9 +167,8 @@
void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
Builder = &builder;
- StmtEntryNode = builder.getLastNode();
+ EntryNode = builder.getLastNode();
CurrentStmt = S;
- NodeSet Dst;
// Set up our simple checks.
@@ -187,49 +186,53 @@
// Create the cleaned state.
- CleanedState = StateMgr.RemoveDeadBindings(StmtEntryNode->getState(),
- CurrentStmt, Liveness,
- DeadSymbols);
+ CleanedState = StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt,
+ Liveness, DeadSymbols);
// Process any special transfer function for dead symbols.
NodeSet Tmp;
if (DeadSymbols.empty())
- Tmp.Add(StmtEntryNode);
+ Tmp.Add(EntryNode);
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);
+ SaveOr OldHasGen(Builder->HasGeneratedNode);
+
+ TF->EvalDeadSymbols(Tmp, *this, *Builder, EntryNode->getLocation(),
+ EntryNode, CleanedState, DeadSymbols);
+
+ if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
+ Tmp.Add(EntryNode);
}
-
+
+ bool HasAutoGenerated = false;
+
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
+ NodeSet Dst;
+
// Set the cleaned state.
- Builder->SetCleanedState(*I == StmtEntryNode ? CleanedState : (*I)->getState());
-
+ Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
+
// Visit the statement.
- Visit(S, StmtEntryNode, Dst);
+ Visit(S, *I, Dst);
+
+ // Do we need to auto-generate a node? We only need to do this to generate
+ // a node with a "cleaned" state; GRCoreEngine will actually handle
+ // auto-transitions for other cases.
+ if (Dst.size() == 1 && *Dst.begin() == EntryNode
+ && !Builder->HasGeneratedNode && !HasAutoGenerated) {
+ HasAutoGenerated = true;
+ builder.generateNode(S, GetState(EntryNode), *I);
+ }
}
- // If no nodes were generated, generate a new node that has all the
- // dead mappings removed.
-
- if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode &&
- !Builder->HasGeneratedNode)
- builder.generateNode(S, GetState(StmtEntryNode), StmtEntryNode);
-
// NULL out these variables to cleanup.
-
- CurrentStmt = NULL;
- StmtEntryNode = NULL;
- Builder = NULL;
CleanedState = NULL;
+ EntryNode = NULL;
+ CurrentStmt = NULL;
+ Builder = NULL;
}
void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {