[cfe-commits] r46137 - in /cfe/trunk: Analysis/DeadStores.cpp Analysis/GRConstants.cpp Analysis/LiveVariables.cpp include/clang/Analysis/Analyses/LiveVariables.h include/clang/Analysis/FlowSensitive/DataflowSolver.h include/clang/Analysis/FlowSensitive/DataflowValues.h
Ted Kremenek
kremenek at apple.com
Thu Jan 17 10:25:22 PST 2008
Author: kremenek
Date: Thu Jan 17 12:25:22 2008
New Revision: 46137
URL: http://llvm.org/viewvc/llvm-project?rev=46137&view=rev
Log:
Added support to dataflow solver to (when requested) also record dataflow
values for the block-level expressions.
Modified 'LiveVariables' to provide the option to clients to record
liveness information for block-level expressions (using the above feature).
Modified 'DeadStores' to conform to the new interface of 'LiveVariables'.
Modified 'GRConstants' to compute liveness information for block-level
expressions.
Modified:
cfe/trunk/Analysis/DeadStores.cpp
cfe/trunk/Analysis/GRConstants.cpp
cfe/trunk/Analysis/LiveVariables.cpp
cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h
cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h
cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h
Modified: cfe/trunk/Analysis/DeadStores.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/DeadStores.cpp?rev=46137&r1=46136&r2=46137&view=diff
==============================================================================
--- cfe/trunk/Analysis/DeadStores.cpp (original)
+++ cfe/trunk/Analysis/DeadStores.cpp Thu Jan 17 12:25:22 2008
@@ -80,7 +80,7 @@
LiveVariables L(cfg);
L.runOnCFG(cfg);
DeadStoreObs A(Ctx, Diags);
- L.runOnAllBlocks(cfg,A);
+ L.runOnAllBlocks(cfg,&A);
}
} // end namespace clang
Modified: cfe/trunk/Analysis/GRConstants.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRConstants.cpp?rev=46137&r1=46136&r2=46137&view=diff
==============================================================================
--- cfe/trunk/Analysis/GRConstants.cpp (original)
+++ cfe/trunk/Analysis/GRConstants.cpp Thu Jan 17 12:25:22 2008
@@ -189,6 +189,7 @@
cfg = &c;
Liveness = new LiveVariables(c);
Liveness->runOnCFG(c);
+ Liveness->runOnAllBlocks(c, NULL, true);
}
StateTy getInitialState() {
@@ -274,9 +275,6 @@
GRConstants::StateTy
GRConstants::RemoveSubExprMappings(StateTy M) {
-#if 0
- return M;
-#else
for (StateTy::iterator I = M.begin(), E = M.end();
I!=E && I.getKey().getKind() == DSPtr::IsSubExp; ++I) {
// Note: we can assign a new map to M since the iterators are
@@ -286,16 +284,12 @@
}
return M;
-#endif
}
GRConstants::StateTy
GRConstants::RemoveDescendantMappings(Stmt* S, GRConstants::StateTy State,
unsigned Levels) {
-#if 1
- return State;
-#else
typedef Stmt::child_iterator iterator;
for (iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
@@ -317,7 +311,6 @@
}
return State;
-#endif
}
void GRConstants::DoStmt(Stmt* S) {
@@ -357,8 +350,11 @@
void GRConstants::VisitBinAssign(BinaryOperator* B) {
- if (DeclRefExpr* D = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParens()))
- AddBinding(D->getDecl(), GetBinding(B->getRHS()));
+ if (DeclRefExpr* D = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParens())) {
+ ExprVariantTy V = GetBinding(B->getRHS());
+ AddBinding(D->getDecl(), V);
+ AddBinding(B, V);
+ }
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/LiveVariables.cpp?rev=46137&r1=46136&r2=46137&view=diff
==============================================================================
--- cfe/trunk/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/Analysis/LiveVariables.cpp Thu Jan 17 12:25:22 2008
@@ -165,11 +165,12 @@
}
void LiveVariables::runOnAllBlocks(const CFG& cfg,
- LiveVariables::ObserverTy& Obs) {
+ LiveVariables::ObserverTy* Obs,
+ bool recordStmtValues) {
Solver S(*this);
ObserverTy* OldObserver = getAnalysisData().Observer;
- getAnalysisData().Observer = &Obs;
- S.runOnAllBlocks(cfg);
+ getAnalysisData().Observer = Obs;
+ S.runOnAllBlocks(cfg, recordStmtValues);
getAnalysisData().Observer = OldObserver;
}
Modified: cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h?rev=46137&r1=46136&r2=46137&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h Thu Jan 17 12:25:22 2008
@@ -70,6 +70,12 @@
/// IsLive - Return true if a variable is live at beginning of a
/// specified block.
bool isLive(const CFGBlock* B, const VarDecl* D) const;
+
+ /// IsLive - Returns true if a variable is live at the beginning of the
+ /// the statement. This query only works if liveness information
+ /// has been recorded at the statement level (see runOnAllBlocks), and
+ /// only returns liveness information for block-level expressions.
+ bool isLive(const Stmt* S, const VarDecl* D) const;
/// IsLive - Return true if a variable is live according to the
/// provided livness bitvector.
@@ -93,7 +99,13 @@
void InitializeValues(const CFG& cfg);
void runOnCFG(CFG& cfg);
- void runOnAllBlocks(const CFG& cfg, ObserverTy& Obs);
+
+ /// runOnAllBlocks - Propagate the dataflow values once for each block,
+ /// starting from the current dataflow values. 'recordStmtValues' indicates
+ /// whether the method should store dataflow values per each individual
+ /// block-level expression.
+ void runOnAllBlocks(const CFG& cfg, ObserverTy* Obs,
+ bool recordStmtValues=false);
};
} // end namespace clang
Modified: cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h?rev=46137&r1=46136&r2=46137&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h (original)
+++ cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h Thu Jan 17 12:25:22 2008
@@ -140,12 +140,12 @@
~DataflowSolver() {}
/// runOnCFG - Computes dataflow values for all blocks in a CFG.
- void runOnCFG(CFG& cfg) {
+ void runOnCFG(CFG& cfg, bool recordStmtValues = false) {
// Set initial dataflow values and boundary conditions.
D.InitializeValues(cfg);
// Solve the dataflow equations. This will populate D.EdgeDataMap
// with dataflow values.
- SolveDataflowEquations(cfg);
+ SolveDataflowEquations(cfg, recordStmtValues);
}
/// runOnBlock - Computes dataflow values for a given block. This
@@ -153,23 +153,29 @@
/// dataflow values using runOnCFG, as runOnBlock is intended to
/// only be used for querying the dataflow values within a block
/// with and Observer object.
- void runOnBlock(const CFGBlock* B) {
+ void runOnBlock(const CFGBlock* B, bool recordStmtValues) {
BlockDataMapTy& M = D.getBlockDataMap();
typename BlockDataMapTy::iterator I = M.find(B);
if (I != M.end()) {
TF.getVal().copyValues(I->second);
- ProcessBlock(B);
+ ProcessBlock(B, recordStmtValues);
}
}
- void runOnBlock(const CFGBlock& B) { runOnBlock(&B); }
- void runOnBlock(CFG::iterator& I) { runOnBlock(*I); }
- void runOnBlock(CFG::const_iterator& I) { runOnBlock(*I); }
+ void runOnBlock(const CFGBlock& B, bool recordStmtValues) {
+ runOnBlock(&B, recordStmtValues);
+ }
+ void runOnBlock(CFG::iterator& I, bool recordStmtValues) {
+ runOnBlock(*I, recordStmtValues);
+ }
+ void runOnBlock(CFG::const_iterator& I, bool recordStmtValues) {
+ runOnBlock(*I, recordStmtValues);
+ }
- void runOnAllBlocks(const CFG& cfg) {
+ void runOnAllBlocks(const CFG& cfg, bool recordStmtValues = false) {
for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
- runOnBlock(I);
+ runOnBlock(I, recordStmtValues);
}
//===----------------------------------------------------===//
@@ -180,13 +186,13 @@
/// SolveDataflowEquations - Perform the actual worklist algorithm
/// to compute dataflow values.
- void SolveDataflowEquations(CFG& cfg) {
+ void SolveDataflowEquations(CFG& cfg, bool recordStmtValues) {
EnqueueFirstBlock(cfg,AnalysisDirTag());
while (!WorkList.isEmpty()) {
const CFGBlock* B = WorkList.dequeue();
ProcessMerge(cfg,B);
- ProcessBlock(B);
+ ProcessBlock(B, recordStmtValues);
UpdateEdges(cfg,B,TF.getVal());
}
}
@@ -228,9 +234,11 @@
/// ProcessBlock - Process the transfer functions for a given block.
- void ProcessBlock(const CFGBlock* B) {
- for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E; ++I)
+ void ProcessBlock(const CFGBlock* B, bool recordStmtValues) {
+ for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
TF.BlockStmt_Visit(const_cast<Stmt*>(*I));
+ if (recordStmtValues) D.getStmtDataMap()[*I] = TF.getVal();
+ }
}
/// UpdateEdges - After processing the transfer functions for a
Modified: cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h?rev=46137&r1=46136&r2=46137&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h (original)
+++ cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h Thu Jan 17 12:25:22 2008
@@ -50,6 +50,7 @@
typedef _AnalysisDirTag AnalysisDirTag;
typedef llvm::DenseMap<ProgramPoint, ValTy> EdgeDataMapTy;
typedef llvm::DenseMap<const CFGBlock*, ValTy> BlockDataMapTy;
+ typedef llvm::DenseMap<const Stmt*, ValTy> StmtDataMapTy;
//===--------------------------------------------------------------------===//
// Predicates.
@@ -73,6 +74,9 @@
//===--------------------------------------------------------------------===//
public:
+ DataflowValues() : StmtDataMap(NULL) {}
+ ~DataflowValues() { delete StmtDataMap; }
+
/// InitializeValues - Invoked by the solver to initialize state needed for
/// dataflow analysis. This method is usually specialized by subclasses.
void InitializeValues(const CFG& cfg) {};
@@ -102,7 +106,24 @@
const ValTy& getBlockData(const CFGBlock* B) const {
return const_cast<DataflowValues*>(this)->getBlockData(B);
- }
+ }
+
+ /// getStmtData - Retrieves the dataflow values associated with a
+ /// specified Stmt. If the dataflow analysis is a forward analysis,
+ /// this data corresponds to the point immediately after a Stmt.
+ /// If the analysis is a backwards analysis, it is associated with
+ /// the point before a Stmt. This data is only computed for block-level
+ /// expressions, and only when requested when the analysis is executed.
+ ValTy& getStmtData(const Stmt* S) {
+ assert (StmtDataMap && "Dataflow values were not computed for statements.");
+ typename StmtDataMapTy::iterator I = StmtDataMap->find(S);
+ assert (I != StmtDataMap->end() && "No data associated with statement.");
+ return I->second;
+ }
+
+ const ValTy& getStmtData(const Stmt* S) const {
+ return const_cast<DataflowValues*>(this)->getStmtData(S);
+ }
/// getEdgeDataMap - Retrieves the internal map between CFG edges and
/// dataflow values. Usually used by a dataflow solver to compute
@@ -117,6 +138,17 @@
/// to the dataflow values at the end of the block.
BlockDataMapTy& getBlockDataMap() { return BlockDataMap; }
const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; }
+
+ /// getStmtDataMap - Retrieves the internal map between Stmts and
+ /// dataflow values.
+ StmtDataMapTy& getStmtDataMap() {
+ if (!StmtDataMap) StmtDataMap = new StmtDataMapTy();
+ return *StmtDataMap;
+ }
+
+ const StmtDataMapTy& getStmtDataMap() const {
+ return const_cast<DataflowValues*>(this)->getStmtDataMap();
+ }
/// getAnalysisData - Retrieves the meta data associated with a
/// dataflow analysis for analyzing a particular CFG.
@@ -132,6 +164,7 @@
protected:
EdgeDataMapTy EdgeDataMap;
BlockDataMapTy BlockDataMap;
+ StmtDataMapTy* StmtDataMap;
AnalysisDataTy AnalysisData;
};
More information about the cfe-commits
mailing list