From: Chris Lattner Date: Sun, 22 Jul 2007 07:28:00 +0000 (+0000) Subject: Implement a simple cache in headersearch. This speeds up X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9960ae8ecfa2c4278dac708a02e463f83fdf17e8;p=clang Implement a simple cache in headersearch. This speeds up preprocessing 483.xalancbmk by about 10%, reducing the number of file lookup queries from 2139411 to 199466 (over 10x) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40390 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Lex/HeaderSearch.cpp b/Lex/HeaderSearch.cpp index 520205e1da..96c86939b7 100644 --- a/Lex/HeaderSearch.cpp +++ b/Lex/HeaderSearch.cpp @@ -163,6 +163,26 @@ const FileEntry *HeaderSearch::LookupFile(const char *FilenameStart, if (FromDir) i = FromDir-&SearchDirs[0]; + // Cache all of the lookups performed by this method. Many headers are + // multiply included, and the "pragma once" optimization prevents them from + // being relex/pp'd, but they would still have to search through a + // (potentially huge) series of SearchDirs to find it. + std::pair &CacheLookup = + LookupFileCache.GetOrCreateValue(FilenameStart, FilenameEnd).getValue(); + + // If the entry has been previously looked up, the first value will be + // non-zero. If the value is equal to i (the start point of our search), then + // this is a matching hit. + if (CacheLookup.first == i+1) { + // Skip querying potentially lots of directories for this lookup. + i = CacheLookup.second; + } else { + // Otherwise, this is the first query, or the previous query didn't match + // our search start. We will fill in our found location below, so prime the + // start point value. + CacheLookup.first = i+1; + } + // Check each directory in sequence to see if it contains this file. for (; i != SearchDirs.size(); ++i) { const FileEntry *FE = 0; @@ -183,11 +203,15 @@ const FileEntry *HeaderSearch::LookupFile(const char *FilenameStart, // This file is a system header or C++ unfriendly if the dir is. getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic(); + + // Remember this location for the next lookup we do. + CacheLookup.second = i; return FE; } } - // Otherwise, didn't find it. + // Otherwise, didn't find it. Remember we didn't find this. + CacheLookup.second = SearchDirs.size(); return 0; } diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 79b3366ecd..4163a8a07f 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -68,6 +68,15 @@ class HeaderSearch { /// std::vector FileInfo; + /// LookupFileCache - This is keeps track of each lookup performed by + /// LookupFile. The first part of the value is the starting index in + /// SearchDirs that the cached search was performed from. If there is a hit + /// and this value doesn't match the current query, the cache has to be + /// ignored. The second value is the entry in SearchDirs that satisfied the + /// query. + llvm::StringMap > LookupFileCache; + + /// FrameworkMap - This is a collection mapping a framework or subframework /// name like "Carbon" to the Carbon.framework directory. llvm::StringMap FrameworkMap; @@ -88,6 +97,7 @@ public: SearchDirs = dirs; SystemDirIdx = systemDirIdx; NoCurDirSearch = noCurDirSearch; + //LookupFileCache.clear(); } /// ClearFileInfo - Forget everything we know about headers so far.