From: Anna Zaks Date: Tue, 13 Mar 2012 19:32:19 +0000 (+0000) Subject: [analyzer] Change the order in which we analyze the functions under X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b990d039c7e01ad0055dcbd1e13a691813397b96;p=clang [analyzer] Change the order in which we analyze the functions under inlining to be the reverse of their declaration. This optimizes running time under inlining up to 20% since we do not re-analyze the utility functions which are usually defined first in the translation unit if they have already been analyzed while inlined into the root functions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152653 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index e8903804f9..5cf9e31c5b 100644 --- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -272,21 +272,25 @@ void AnalysisConsumer::HandleDeclsGallGraph(TranslationUnitDecl *TU) { // Find the top level nodes - children of root + the unreachable (parentless) // nodes. llvm::SmallVector TopLevelFunctions; + for (CallGraph::nodes_iterator TI = CG.parentless_begin(), + TE = CG.parentless_end(); TI != TE; ++TI) { + TopLevelFunctions.push_back(*TI); + NumFunctionTopLevel++; + } CallGraphNode *Entry = CG.getRoot(); for (CallGraphNode::iterator I = Entry->begin(), E = Entry->end(); I != E; ++I) { TopLevelFunctions.push_back(*I); NumFunctionTopLevel++; } - for (CallGraph::nodes_iterator TI = CG.parentless_begin(), - TE = CG.parentless_end(); TI != TE; ++TI) { - TopLevelFunctions.push_back(*TI); - NumFunctionTopLevel++; - } + // Make sure the nodes are sorted in order reverse of their definition in the + // translation unit. This step is very important for performance. It ensures + // that we analyze the root functions before the externally available + // subroutines. std::queue BFSQueue; - for (llvm::SmallVector::iterator - TI = TopLevelFunctions.begin(), TE = TopLevelFunctions.end(); + for (llvm::SmallVector::reverse_iterator + TI = TopLevelFunctions.rbegin(), TE = TopLevelFunctions.rend(); TI != TE; ++TI) BFSQueue.push(*TI); diff --git a/test/Analysis/inline-unique-reports.c b/test/Analysis/inline-unique-reports.c index 1cc3130c47..83df2d84de 100644 --- a/test/Analysis/inline-unique-reports.c +++ b/test/Analysis/inline-unique-reports.c @@ -34,12 +34,12 @@ void test_bug_2() { // CHECK: start // CHECK: // CHECK: -// CHECK: line9 +// CHECK: line14 // CHECK: col3 // CHECK: file0 // CHECK: // CHECK: -// CHECK: line9 +// CHECK: line14 // CHECK: col3 // CHECK: file0 // CHECK: @@ -47,12 +47,12 @@ void test_bug_2() { // CHECK: end // CHECK: // CHECK: -// CHECK: line10 +// CHECK: line15 // CHECK: col3 // CHECK: file0 // CHECK: // CHECK: -// CHECK: line10 +// CHECK: line15 // CHECK: col3 // CHECK: file0 // CHECK: @@ -64,7 +64,7 @@ void test_bug_2() { // CHECK: kindevent // CHECK: location // CHECK: -// CHECK: line10 +// CHECK: line15 // CHECK: col3 // CHECK: file0 // CHECK: @@ -72,12 +72,12 @@ void test_bug_2() { // CHECK: // CHECK: // CHECK: -// CHECK: line10 +// CHECK: line15 // CHECK: col3 // CHECK: file0 // CHECK: // CHECK: -// CHECK: line10 +// CHECK: line15 // CHECK: col8 // CHECK: file0 // CHECK: diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m index 96bc7a9b3e..7c46426a81 100644 --- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m +++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m @@ -80,16 +80,16 @@ int handleVoidInComma() { int marker(void) { // control reaches end of non-void function } - -// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage // CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage -// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage // CHECK-darwin8: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage +// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage // CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage -// CHECK-darwin9-NOT: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage +// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage + // CHECK-darwin9-NOT: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage -// CHECK-darwin9-NOT: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage // CHECK-darwin9-NOT: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage +// CHECK-darwin9-NOT: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage // CHECK-darwin9-NOT: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage +// CHECK-darwin9-NOT: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage // CHECK-darwin9: 1 warning generated