aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Analysis/FlowSensitive
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-01-17 18:25:22 +0000
committerTed Kremenek <kremenek@apple.com>2008-01-17 18:25:22 +0000
commit79649dfed2fc4b8cf0f7b6890df69458dbceeb04 (patch)
tree7b8066966f019d89c91463b937c25c069db1bdab /include/clang/Analysis/FlowSensitive
parenteed50586435ce4d2690f44ceabd69ad531d80970 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46137 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis/FlowSensitive')
-rw-r--r--include/clang/Analysis/FlowSensitive/DataflowSolver.h34
-rw-r--r--include/clang/Analysis/FlowSensitive/DataflowValues.h35
2 files changed, 55 insertions, 14 deletions
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
index 12ca5b9271..02619f5496 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -140,12 +140,12 @@ public:
~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 @@ public:
/// 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 @@ private:
/// 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 @@ private:
/// 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
diff --git a/include/clang/Analysis/FlowSensitive/DataflowValues.h b/include/clang/Analysis/FlowSensitive/DataflowValues.h
index 1604b88e30..be0a960149 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowValues.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowValues.h
@@ -50,6 +50,7 @@ public:
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 @@ private:
//===--------------------------------------------------------------------===//
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 @@ public:
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 @@ public:
/// 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 @@ public:
protected:
EdgeDataMapTy EdgeDataMap;
BlockDataMapTy BlockDataMap;
+ StmtDataMapTy* StmtDataMap;
AnalysisDataTy AnalysisData;
};