[cfe-commits] r152652 - /cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
Anna Zaks
ganna at apple.com
Tue Mar 13 12:32:13 PDT 2012
Author: zaks
Date: Tue Mar 13 14:32:13 2012
New Revision: 152652
URL: http://llvm.org/viewvc/llvm-project?rev=152652&view=rev
Log:
[analyzer] Use BFS over call graph when analysing functions.
BFS should give slightly better performance. Ex: Suppose, we have two
roots R1 and R2. A callee function C is reachable through both. However,
C is not inlined when analyzing R1 due to inline stack depth limit. With
DFS, C will be analyzed as top level even though it would be analyzed as
inlined through R2. On the other hand, BFS could avoid analyzing C as
top level.
Modified:
cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=152652&r1=152651&r2=152652&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Tue Mar 13 14:32:13 2012
@@ -43,6 +43,8 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Statistic.h"
+#include <queue>
+
using namespace clang;
using namespace ento;
using llvm::SmallPtrSet;
@@ -282,31 +284,45 @@
NumFunctionTopLevel++;
}
- // TODO: Sort TopLevelFunctions.
+ std::queue<CallGraphNode*> BFSQueue;
+ for (llvm::SmallVector<CallGraphNode*, 24>::iterator
+ TI = TopLevelFunctions.begin(), TE = TopLevelFunctions.end();
+ TI != TE; ++TI)
+ BFSQueue.push(*TI);
- // DFS over all of the top level nodes. Use external Visited set, which is
+ // BFS over all of the functions, while skipping the ones inlined into
+ // the previously processed functions. Use external Visited set, which is
// also modified when we inline a function.
SmallPtrSet<CallGraphNode*,24> Visited;
- for (llvm::SmallVector<CallGraphNode*, 24>::iterator
- TI = TopLevelFunctions.begin(), TE = TopLevelFunctions.end();
- TI != TE; ++TI) {
- for (llvm::df_ext_iterator<CallGraphNode*, SmallPtrSet<CallGraphNode*,24> >
- DFI = llvm::df_ext_begin(*TI, Visited),
- E = llvm::df_ext_end(*TI, Visited);
- DFI != E; ++DFI) {
- SetOfDecls VisitedCallees;
- Decl *D = (*DFI)->getDecl();
- assert(D);
- HandleCode(D, ANALYSIS_PATH,
- (Mgr->InliningMode == All ? 0 : &VisitedCallees));
-
- // Add the visited callees to the global visited set.
- for (SetOfDecls::const_iterator I = VisitedCallees.begin(),
- E = VisitedCallees.end(); I != E; ++I) {
- CallGraphNode *VN = CG.getNode(*I);
- if (VN)
- Visited.insert(VN);
- }
+ while(!BFSQueue.empty()) {
+ CallGraphNode *N = BFSQueue.front();
+ BFSQueue.pop();
+
+ // Skip the functions which have been processed already or previously
+ // inlined.
+ if (Visited.count(N))
+ continue;
+
+ // Analyze the function.
+ SetOfDecls VisitedCallees;
+ Decl *D = N->getDecl();
+ assert(D);
+ HandleCode(D, ANALYSIS_PATH,
+ (Mgr->InliningMode == All ? 0 : &VisitedCallees));
+
+ // Add the visited callees to the global visited set.
+ for (SetOfDecls::const_iterator I = VisitedCallees.begin(),
+ E = VisitedCallees.end(); I != E; ++I) {
+ CallGraphNode *VN = CG.getNode(*I);
+ if (VN)
+ Visited.insert(VN);
+ }
+ Visited.insert(N);
+
+ // Push the children into the queue.
+ for (CallGraphNode::const_iterator CI = N->begin(),
+ CE = N->end(); CI != CE; ++CI) {
+ BFSQueue.push(*CI);
}
}
}
More information about the cfe-commits
mailing list