summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-04-12 22:36:48 +0000
committerAnna Zaks <ganna@apple.com>2012-04-12 22:36:48 +0000
commit6a86082f3a06a2dcceaaf63f78a0e52d64bcbaa3 (patch)
treecf41e29ac97fff116c78975aeecda1a68594e741 /include
parent273ed9870aa064992fb3c25a1f4d8973b10ad36e (diff)
[analyzer] PCH deserialization optimization.
We should not deserialize unused declarations from the PCH file. Achieve this by storing the top level declarations during parsing (HandleTopLevelDecl ASTConsumer callback) and analyzing/building a call graph only for those. Tested the patch on a sample ObjC file that uses PCH. With the patch, the analyzes is 17.5% faster and clang consumes 40% less memory. Got about 10% overall build/analyzes time decrease on a large Objective C project. A bit of CallGraph refactoring/cleanup as well.. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154625 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/Analysis/CallGraph.h51
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h3
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h3
4 files changed, 50 insertions, 11 deletions
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index f1b6e64772..9b6807343c 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -18,6 +18,7 @@
#define LLVM_CLANG_ANALYSIS_CALLGRAPH
#include "clang/AST/DeclBase.h"
+#include "clang/AST/RecursiveASTVisitor.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SetVector.h"
@@ -25,8 +26,14 @@
namespace clang {
class CallGraphNode;
-class CallGraph {
+/// \class The AST-based call graph.
+///
+/// The call graph extends itself with the given declarations by implementing
+/// the recursive AST visitor, which constructs the graph by visiting the given
+/// declarations.
+class CallGraph : public RecursiveASTVisitor<CallGraph> {
friend class CallGraphNode;
+
typedef llvm::DenseMap<const Decl *, CallGraphNode *> FunctionMapTy;
/// FunctionMap owns all CallGraphNodes.
@@ -45,19 +52,23 @@ public:
CallGraph();
~CallGraph();
- /// \brief Add the given declaration to the call graph.
- void addToCallGraph(Decl *D, bool IsGlobal);
+ /// \brief Populate the call graph with the functions in the given
+ /// declaration.
+ ///
+ /// Recursively walks the declaration to find all the dependent Decls as well.
+ void addToCallGraph(Decl *D) {
+ TraverseDecl(D);
+ }
- /// \brief Populate the call graph with the functions in the given translation
- /// unit.
- void addToCallGraph(TranslationUnitDecl *TU);
+ /// \brief Determine if a declaration should be included in the graph.
+ static bool includeInGraph(const Decl *D);
/// \brief Lookup the node for the given declaration.
CallGraphNode *getNode(const Decl *) const;
/// \brief Lookup the node for the given declaration. If none found, insert
/// one into the graph.
- CallGraphNode *getOrInsertFunction(Decl *);
+ CallGraphNode *getOrInsertNode(Decl *);
/// Iterators through all the elements in the graph. Note, this gives
/// non-deterministic order.
@@ -90,6 +101,32 @@ public:
void print(raw_ostream &os) const;
void dump() const;
void viewGraph() const;
+
+ /// Part of recursive declaration visitation.
+ bool VisitFunctionDecl(FunctionDecl *FD) {
+ // We skip function template definitions, as their semantics is
+ // only determined when they are instantiated.
+ if (includeInGraph(FD))
+ // If this function has external linkage, anything could call it.
+ // Note, we are not precise here. For example, the function could have
+ // its address taken.
+ addNodeForDecl(FD, FD->isGlobal());
+ return true;
+ }
+
+ /// Part of recursive declaration visitation.
+ bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+ if (includeInGraph(MD))
+ addNodeForDecl(MD, true);
+ return true;
+ }
+
+private:
+ /// \brief Add the given declaration to the call graph.
+ void addNodeForDecl(Decl *D, bool IsGlobal);
+
+ /// \brief Allocate a new node in the graph.
+ CallGraphNode *allocateNewNode(Decl *);
};
class CallGraphNode {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index d9156441db..59136fc314 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -82,7 +82,7 @@ private:
/// The functions which have been analyzed through inlining. This is owned by
/// AnalysisConsumer. It can be null.
- SetOfDecls *AnalyzedCallees;
+ SetOfConstDecls *AnalyzedCallees;
/// The information about functions shared by the whole translation unit.
/// (This data is owned by AnalysisConsumer.)
@@ -109,7 +109,7 @@ private:
public:
/// Construct a CoreEngine object to analyze the provided CFG using
/// a DFS exploration of the exploded graph.
- CoreEngine(SubEngine& subengine, SetOfDecls *VisitedCallees,
+ CoreEngine(SubEngine& subengine, SetOfConstDecls *VisitedCallees,
FunctionSummariesTy *FS)
: SubEng(subengine), G(new ExplodedGraph()),
WList(WorkList::makeBFS()),
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 7b31172e33..2a21a03e9a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -91,7 +91,8 @@ class ExprEngine : public SubEngine {
GRBugReporter BR;
public:
- ExprEngine(AnalysisManager &mgr, bool gcEnabled, SetOfDecls *VisitedCallees,
+ ExprEngine(AnalysisManager &mgr, bool gcEnabled,
+ SetOfConstDecls *VisitedCallees,
FunctionSummariesTy *FS);
~ExprEngine();
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
index 33943d9f1c..42adff3e2b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
@@ -21,7 +21,8 @@
namespace clang {
namespace ento {
-typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls;
+typedef llvm::SmallPtrSet<Decl*, 24> SetOfDecls;
+typedef llvm::SmallPtrSet<const Decl*, 24> SetOfConstDecls;
class FunctionSummariesTy {
struct FunctionSummary {