]> granicus.if.org Git - clang/commitdiff
Implement a simple cache in headersearch. This speeds up
authorChris Lattner <sabre@nondot.org>
Sun, 22 Jul 2007 07:28:00 +0000 (07:28 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 22 Jul 2007 07:28:00 +0000 (07:28 +0000)
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

Lex/HeaderSearch.cpp
include/clang/Lex/HeaderSearch.h

index 520205e1dae289b5a470e665cf920b9a1c9a1f16..96c86939b77d8ab57a0229bd53d6aa24eae7ebef 100644 (file)
@@ -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<unsigned, unsigned> &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;
 }
 
index 79b3366ecd5658d53ed3e8e123a2834107de73f5..4163a8a07f2bf8d790a6b7522277f3359f909db9 100644 (file)
@@ -68,6 +68,15 @@ class HeaderSearch {
   ///
   std::vector<PerFileInfo> 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<std::pair<unsigned, unsigned> > LookupFileCache;
+  
+  
   /// FrameworkMap - This is a collection mapping a framework or subframework
   /// name like "Carbon" to the Carbon.framework directory.
   llvm::StringMap<const DirectoryEntry *> FrameworkMap;
@@ -88,6 +97,7 @@ public:
     SearchDirs = dirs;
     SystemDirIdx = systemDirIdx;
     NoCurDirSearch = noCurDirSearch;
+    //LookupFileCache.clear();
   }
   
   /// ClearFileInfo - Forget everything we know about headers so far.