[cfe-commits] r169589 - /cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
Ted Kremenek
kremenek at apple.com
Thu Dec 6 23:30:19 PST 2012
Author: kremenek
Date: Fri Dec 7 01:30:19 2012
New Revision: 169589
URL: http://llvm.org/viewvc/llvm-project?rev=169589&view=rev
Log:
Cache queries to lookupPrivateMethod() within ObjCMethodCall::getRuntimeDefinition().
The same queries can happen thousands of times. This reduces the analysis
time on one heavy Objective-C file by 2.4%.
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=169589&r1=169588&r2=169589&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Fri Dec 7 01:30:19 2012
@@ -835,7 +835,35 @@
// Lookup the method implementation.
if (ReceiverT)
if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl()) {
- const ObjCMethodDecl *MD = IDecl->lookupPrivateMethod(Sel);
+ // Repeatedly calling lookupPrivateMethod() is expensive, especially
+ // when in many cases it returns null. We cache the results so
+ // that repeated queries on the same ObjCIntefaceDecl and Selector
+ // don't incur the same cost. On some test cases, we can see the
+ // same query being issued thousands of times.
+ //
+ // NOTE: This cache is essentially a "global" variable, but it
+ // only gets lazily created when we get here. The value of the
+ // cache probably comes from it being global across ExprEngines,
+ // where the same queries may get issued. If we are worried about
+ // concurrency, or possibly loading/unloading ASTs, etc., we may
+ // need to revisit this someday. In terms of memory, this table
+ // stays around until clang quits, which also may be bad if we
+ // need to release memory.
+ typedef std::pair<const ObjCInterfaceDecl*, Selector>
+ PrivateMethodKey;
+ typedef llvm::DenseMap<PrivateMethodKey,
+ llvm::Optional<const ObjCMethodDecl *> >
+ PrivateMethodCache;
+
+ static PrivateMethodCache PMC;
+ llvm::Optional<const ObjCMethodDecl *> &Val =
+ PMC[std::make_pair(IDecl, Sel)];
+
+ // Query lookupPrivateMethod() if the cache does not hit.
+ if (!Val.hasValue())
+ Val = IDecl->lookupPrivateMethod(Sel);
+
+ const ObjCMethodDecl *MD = Val.getValue();
if (CanBeSubClassed)
return RuntimeDefinition(MD, Receiver);
else
More information about the cfe-commits
mailing list