forked from OSchip/llvm-project
Refine SourceManager's isBeforeInTranslationUnit() cache to have more entries.
isBeforeInTranslationUnit() uses a cache to reduce the expensive work to compute a common ancestor for two FileIDs. This work is very expensive, so even caching the latest used FileIDs was a big win. A closer analysis of the cache before, however, shows that the cache access pattern would oscillate between a working set of FileIDs, and thus caching more pairs would be profitable. This patch adds a side table for extending caching. This side table is bounded in size (experimentally determined in this case from a simple Objective-C project), and when the table gets too large we fall back to the single entry caching before as before. On Sketch (a small example Objective-C project), this optimization reduces -fsyntax-only time on SKTGraphicView.m by 5%. This is for a project that is already using PCH. Fixes <rdar://problem/13299847> llvm-svn: 176142
This commit is contained in:
parent
07c446baf4
commit
08037045f8
|
@ -447,7 +447,7 @@ public:
|
|||
///
|
||||
/// The cache structure is complex enough to be worth breaking out of
|
||||
/// SourceManager.
|
||||
class IsBeforeInTranslationUnitCache {
|
||||
class InBeforeInTUCacheEntry {
|
||||
/// \brief The FileID's of the cached query.
|
||||
///
|
||||
/// If these match up with a subsequent query, the result can be reused.
|
||||
|
@ -469,7 +469,6 @@ class IsBeforeInTranslationUnitCache {
|
|||
/// random token in the parent.
|
||||
unsigned LCommonOffset, RCommonOffset;
|
||||
public:
|
||||
|
||||
/// \brief Return true if the currently cached values match up with
|
||||
/// the specified LHS/RHS query.
|
||||
///
|
||||
|
@ -647,8 +646,21 @@ class SourceManager : public RefCountedBase<SourceManager> {
|
|||
// Statistics for -print-stats.
|
||||
mutable unsigned NumLinearScans, NumBinaryProbes;
|
||||
|
||||
// Cache results for the isBeforeInTranslationUnit method.
|
||||
mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache;
|
||||
/// The key value into the IsBeforeInTUCache table.
|
||||
typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
|
||||
|
||||
/// The IsBeforeInTranslationUnitCache is a mapping from FileID pairs
|
||||
/// to cache results.
|
||||
typedef llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry>
|
||||
InBeforeInTUCache;
|
||||
|
||||
/// Cache results for the isBeforeInTranslationUnit method.
|
||||
mutable InBeforeInTUCache IBTUCache;
|
||||
mutable InBeforeInTUCacheEntry IBTUCacheOverflow;
|
||||
|
||||
/// Return the cache entry for comparing the given file IDs
|
||||
/// for isBeforeInTranslationUnit.
|
||||
InBeforeInTUCacheEntry &getInBeforeInTUCache(FileID LFID, FileID RFID) const;
|
||||
|
||||
// Cache for the "fake" buffer used for error-recovery purposes.
|
||||
mutable llvm::MemoryBuffer *FakeBufferForRecovery;
|
||||
|
|
|
@ -1855,7 +1855,32 @@ static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc,
|
|||
Loc = SM.getDecomposedLoc(UpperLoc);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// Return the cache entry for comparing the given file IDs
|
||||
/// for isBeforeInTranslationUnit.
|
||||
InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID,
|
||||
FileID RFID) const {
|
||||
// This is a magic number for limiting the cache size. It was experimentally
|
||||
// derived from a small Objective-C project (where the cache filled
|
||||
// out to ~250 items). We can make it larger if necessary.
|
||||
enum { MagicCacheSize = 300 };
|
||||
IsBeforeInTUCacheKey Key(LFID, RFID);
|
||||
|
||||
// If the cache size isn't too large, do a lookup and if necessary default
|
||||
// construct an entry. We can then return it to the caller for direct
|
||||
// use. When they update the value, the cache will get automatically
|
||||
// updated as well.
|
||||
if (IBTUCache.size() < MagicCacheSize)
|
||||
return IBTUCache[Key];
|
||||
|
||||
// Otherwise, do a lookup that will not construct a new value.
|
||||
InBeforeInTUCache::iterator I = IBTUCache.find(Key);
|
||||
if (I != IBTUCache.end())
|
||||
return I->second;
|
||||
|
||||
// Fall back to the overflow value.
|
||||
return IBTUCacheOverflow;
|
||||
}
|
||||
|
||||
/// \brief Determines the order of 2 source locations in the translation unit.
|
||||
///
|
||||
|
@ -1873,6 +1898,11 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
|
|||
if (LOffs.first == ROffs.first)
|
||||
return LOffs.second < ROffs.second;
|
||||
|
||||
// If we are comparing a source location with multiple locations in the same
|
||||
// file, we get a big win by caching the result.
|
||||
InBeforeInTUCacheEntry &IsBeforeInTUCache =
|
||||
getInBeforeInTUCache(LOffs.first, ROffs.first);
|
||||
|
||||
// If we are comparing a source location with multiple locations in the same
|
||||
// file, we get a big win by caching the result.
|
||||
if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first))
|
||||
|
|
Loading…
Reference in New Issue