Skip to content
Snippets Groups Projects
Commit b467051a authored by Anna Zaks's avatar Anna Zaks
Browse files

[analyzer] Refactor: Store visited Decls instead of CallGraphNodes.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170231 91177308-0d34-0410-b5e6-96231b3b80d8
parent b1f67dbb
No related branches found
No related tags found
No related merge requests found
...@@ -270,8 +270,7 @@ public: ...@@ -270,8 +270,7 @@ public:
/// \brief Determine which inlining mode should be used when this function is /// \brief Determine which inlining mode should be used when this function is
/// analyzed. For example, determines if the callees should be inlined. /// analyzed. For example, determines if the callees should be inlined.
ExprEngine::InliningModes ExprEngine::InliningModes
getInliningModeForFunction(CallGraphNode *N, getInliningModeForFunction(const Decl *D, SetOfConstDecls Visited);
SmallPtrSet<CallGraphNode*,24> Visited);
/// \brief Build the call graph for all the top level decls of this TU and /// \brief Build the call graph for all the top level decls of this TU and
/// use it to define the order in which the functions should be visited. /// use it to define the order in which the functions should be visited.
...@@ -364,10 +363,10 @@ void AnalysisConsumer::storeTopLevelDecls(DeclGroupRef DG) { ...@@ -364,10 +363,10 @@ void AnalysisConsumer::storeTopLevelDecls(DeclGroupRef DG) {
} }
} }
static bool shouldSkipFunction(CallGraphNode *N, static bool shouldSkipFunction(const Decl *D,
SmallPtrSet<CallGraphNode*,24> Visited, SetOfConstDecls Visited,
SmallPtrSet<CallGraphNode*,24> VisitedAsTopLevel) { SetOfConstDecls VisitedAsTopLevel) {
if (VisitedAsTopLevel.count(N)) if (VisitedAsTopLevel.count(D))
return true; return true;
// We want to re-analyse the functions as top level in the following cases: // We want to re-analyse the functions as top level in the following cases:
...@@ -377,16 +376,16 @@ static bool shouldSkipFunction(CallGraphNode *N, ...@@ -377,16 +376,16 @@ static bool shouldSkipFunction(CallGraphNode *N,
// not catch errors within defensive code. // not catch errors within defensive code.
// - We want to reanalyze all ObjC methods as top level to report Retain // - We want to reanalyze all ObjC methods as top level to report Retain
// Count naming convention errors more aggressively. // Count naming convention errors more aggressively.
if (isa<ObjCMethodDecl>(N->getDecl())) if (isa<ObjCMethodDecl>(D))
return false; return false;
// Otherwise, if we visited the function before, do not reanalyze it. // Otherwise, if we visited the function before, do not reanalyze it.
return Visited.count(N); return Visited.count(D);
} }
ExprEngine::InliningModes ExprEngine::InliningModes
AnalysisConsumer::getInliningModeForFunction(CallGraphNode *N, AnalysisConsumer::getInliningModeForFunction(const Decl *D,
SmallPtrSet<CallGraphNode*,24> Visited) { SetOfConstDecls Visited) {
ExprEngine::InliningModes HowToInline = ExprEngine::InliningModes HowToInline =
(Mgr->shouldInlineCall()) ? ExprEngine::Inline_All : (Mgr->shouldInlineCall()) ? ExprEngine::Inline_All :
ExprEngine::Inline_None; ExprEngine::Inline_None;
...@@ -394,10 +393,10 @@ AnalysisConsumer::getInliningModeForFunction(CallGraphNode *N, ...@@ -394,10 +393,10 @@ AnalysisConsumer::getInliningModeForFunction(CallGraphNode *N,
// We want to reanalyze all ObjC methods as top level to report Retain // We want to reanalyze all ObjC methods as top level to report Retain
// Count naming convention errors more aggressively. But we can turn off // Count naming convention errors more aggressively. But we can turn off
// inlining when reanalyzing an already inlined function. // inlining when reanalyzing an already inlined function.
if (Visited.count(N)) { if (Visited.count(D)) {
assert(isa<ObjCMethodDecl>(N->getDecl()) && assert(isa<ObjCMethodDecl>(D) &&
"We are only reanalyzing ObjCMethods."); "We are only reanalyzing ObjCMethods.");
ObjCMethodDecl *ObjCM = cast<ObjCMethodDecl>(N->getDecl()); const ObjCMethodDecl *ObjCM = cast<ObjCMethodDecl>(D);
if (ObjCM->getMethodFamily() != OMF_init) if (ObjCM->getMethodFamily() != OMF_init)
HowToInline = ExprEngine::Inline_None; HowToInline = ExprEngine::Inline_None;
} }
...@@ -446,8 +445,8 @@ void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) { ...@@ -446,8 +445,8 @@ void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) {
// BFS over all of the functions, while skipping the ones inlined into // BFS over all of the functions, while skipping the ones inlined into
// the previously processed functions. Use external Visited set, which is // the previously processed functions. Use external Visited set, which is
// also modified when we inline a function. // also modified when we inline a function.
SmallPtrSet<CallGraphNode*,24> Visited; SetOfConstDecls Visited;
SmallPtrSet<CallGraphNode*,24> VisitedAsTopLevel; SetOfConstDecls VisitedAsTopLevel;
while(!BFSQueue.empty()) { while(!BFSQueue.empty()) {
CallGraphNode *N = BFSQueue.front(); CallGraphNode *N = BFSQueue.front();
BFSQueue.pop_front(); BFSQueue.pop_front();
...@@ -455,31 +454,30 @@ void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) { ...@@ -455,31 +454,30 @@ void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) {
// Push the children into the queue. // Push the children into the queue.
for (CallGraphNode::const_iterator CI = N->begin(), for (CallGraphNode::const_iterator CI = N->begin(),
CE = N->end(); CI != CE; ++CI) { CE = N->end(); CI != CE; ++CI) {
if (!shouldSkipFunction(*CI, Visited, VisitedAsTopLevel)) if (!shouldSkipFunction((*CI)->getDecl(), Visited, VisitedAsTopLevel))
BFSQueue.push_back(*CI); BFSQueue.push_back(*CI);
} }
Decl *D = N->getDecl();
assert(D);
// Skip the functions which have been processed already or previously // Skip the functions which have been processed already or previously
// inlined. // inlined.
if (shouldSkipFunction(N, Visited, VisitedAsTopLevel)) if (shouldSkipFunction(D, Visited, VisitedAsTopLevel))
continue; continue;
// Analyze the function. // Analyze the function.
SetOfConstDecls VisitedCallees; SetOfConstDecls VisitedCallees;
Decl *D = N->getDecl();
assert(D);
HandleCode(D, AM_Path, getInliningModeForFunction(N, Visited), HandleCode(D, AM_Path, getInliningModeForFunction(D, Visited),
(Mgr->options.InliningMode == All ? 0 : &VisitedCallees)); (Mgr->options.InliningMode == All ? 0 : &VisitedCallees));
// Add the visited callees to the global visited set. // Add the visited callees to the global visited set.
for (SetOfConstDecls::iterator I = VisitedCallees.begin(), for (SetOfConstDecls::iterator I = VisitedCallees.begin(),
E = VisitedCallees.end(); I != E; ++I) { E = VisitedCallees.end(); I != E; ++I) {
CallGraphNode *VN = CG.getNode(*I); Visited.insert(*I);
if (VN)
Visited.insert(VN);
} }
VisitedAsTopLevel.insert(N); VisitedAsTopLevel.insert(D);
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment