[cfe-commits] r84263 - in /cfe/trunk: include/clang/Basic/FileManager.h include/clang/Frontend/PCHReader.h lib/Basic/FileManager.cpp lib/Frontend/CacheTokens.cpp lib/Frontend/GeneratePCH.cpp lib/Frontend/PCHReader.cpp lib/Lex/PTHLexer.cpp lib/Lex

Douglas Gregor dgregor at apple.com
Mon Oct 19 20:59:05 PDT 2009


On Oct 19, 2009, at 6:02 PM, Daniel Dunbar <daniel at zuster.org> wrote:

> On Fri, Oct 16, 2009 at 11:18 AM, Douglas Gregor <dgregor at apple.com>  
> wrote:
>> Author: dgregor
>> Date: Fri Oct 16 13:18:30 2009
>> New Revision: 84263
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=84263&view=rev
>> Log:
>> Add support for a chain of stat caches in the FileManager, rather  
>> than
>> only supporting a single stat cache. The immediate benefit of this
>> change is that we can now generate a PCH/AST file when including
>> another PCH file; in the future, the chain of stat caches will likely
>> be useful with multiple levels of PCH files.
>
> Nice! What is the status of PCH/AST generation when including a PCH
> file, are all known issues resolved?

The only known issue remaining is that unreferenced macros in the PCH  
file won't be emitted to the AST. Well, that, and I haven't crammed  
much code through the PCH -> AST path.

  - Doug

> - Daniel
>
>> Added:
>>    cfe/trunk/test/Index/c-index-pch.c
>>    cfe/trunk/test/Index/c-index-pch.h
>> Modified:
>>    cfe/trunk/include/clang/Basic/FileManager.h
>>    cfe/trunk/include/clang/Frontend/PCHReader.h
>>    cfe/trunk/lib/Basic/FileManager.cpp
>>    cfe/trunk/lib/Frontend/CacheTokens.cpp
>>    cfe/trunk/lib/Frontend/GeneratePCH.cpp
>>    cfe/trunk/lib/Frontend/PCHReader.cpp
>>    cfe/trunk/lib/Lex/PTHLexer.cpp
>>    cfe/trunk/lib/Lex/Preprocessor.cpp
>>    cfe/trunk/test/CMakeLists.txt
>>
>> Modified: cfe/trunk/include/clang/Basic/FileManager.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FileManager.h?rev=84263&r1=84262&r2=84263&view=diff
>>
>> === 
>> === 
>> === 
>> =====================================================================
>> --- cfe/trunk/include/clang/Basic/FileManager.h (original)
>> +++ cfe/trunk/include/clang/Basic/FileManager.h Fri Oct 16 13:18:30  
>> 2009
>> @@ -71,16 +71,38 @@
>>   }
>>  };
>>
>> -// FIXME: This is a lightweight shim that is used by FileManager  
>> to cache
>> -//  'stat' system calls.  We will use it with PTH to identify if  
>> caching
>> -//  stat calls in PTH files is a performance win.
>> +/// \brief Abstract interface for introducing a FileManager cache  
>> for 'stat'
>> +/// system calls, which is used by precompiled and pretokenized  
>> headers to
>> +/// improve performance.
>>  class StatSysCallCache {
>> +protected:
>> +  llvm::OwningPtr<StatSysCallCache> NextStatCache;
>> +
>>  public:
>>   virtual ~StatSysCallCache() {}
>> -  virtual int stat(const char *path, struct stat *buf) = 0;
>> +  virtual int stat(const char *path, struct stat *buf) {
>> +    if (getNextStatCache())
>> +      return getNextStatCache()->stat(path, buf);
>> +
>> +    return ::stat(path, buf);
>> +  }
>> +
>> +  /// \brief Sets the next stat call cache in the chain of stat  
>> caches.
>> +  /// Takes ownership of the given stat cache.
>> +  void setNextStatCache(StatSysCallCache *Cache) {
>> +    NextStatCache.reset(Cache);
>> +  }
>> +
>> +  /// \brief Retrieve the next stat call cache in the chain.
>> +  StatSysCallCache *getNextStatCache() { return NextStatCache.get 
>> (); }
>> +
>> +  /// \brief Retrieve the next stat call cache in the chain,  
>> transferring
>> +  /// ownership of this cache (and, transitively, all of the  
>> remaining caches)
>> +  /// to the caller.
>> +  StatSysCallCache *takeNextStatCache() { return NextStatCache.take 
>> (); }
>>  };
>>
>> -/// \brief A stat listener that can be used by FileManager to keep
>> +/// \brief A stat "cache" that can be used by FileManager to keep
>>  /// track of the results of stat() calls that occur throughout the
>>  /// execution of the front end.
>>  class MemorizeStatCalls : public StatSysCallCache {
>> @@ -144,13 +166,22 @@
>>   FileManager();
>>   ~FileManager();
>>
>> -  /// setStatCache - Installs the provided StatSysCallCache object  
>> within
>> -  ///  the FileManager.  Ownership of this object is transferred  
>> to the
>> -  ///  FileManager.
>> -  void setStatCache(StatSysCallCache *statCache) {
>> -    StatCache.reset(statCache);
>> -  }
>> -
>> +  /// \brief Installs the provided StatSysCallCache object within
>> +  /// the FileManager.
>> +  ///
>> +  /// Ownership of this object is transferred to the FileManager.
>> +  ///
>> +  /// \param statCache the new stat cache to install. Ownership of  
>> this
>> +  /// object is transferred to the FileManager.
>> +  ///
>> +  /// \param AtBeginning whether this new stat cache must be  
>> installed at the
>> +  /// beginning of the chain of stat caches. Otherwise, it will be  
>> added to
>> +  /// the end of the chain.
>> +  void addStatCache(StatSysCallCache *statCache, bool AtBeginning  
>> = false);
>> +
>> +  /// \brief Removes the provided StatSysCallCache object from the  
>> file manager.
>> +  void removeStatCache(StatSysCallCache *statCache);
>> +
>>   /// getDirectory - Lookup, cache, and verify the specified  
>> directory.  This
>>   /// returns null if the directory doesn't exist.
>>   ///
>>
>> Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=84263&r1=84262&r2=84263&view=diff
>>
>> === 
>> === 
>> === 
>> =====================================================================
>> --- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
>> +++ cfe/trunk/include/clang/Frontend/PCHReader.h Fri Oct 16  
>> 13:18:30 2009
>> @@ -169,6 +169,11 @@
>>   /// \brief The AST context into which we'll read the PCH file.
>>   ASTContext *Context;
>>
>> +  /// \brief The PCH stat cache installed by this PCHReader, if any.
>> +  ///
>> +  /// The dynamic type of this stat cache is always PCHStatCache
>> +  void *StatCache;
>> +
>>   /// \brief The AST consumer.
>>   ASTConsumer *Consumer;
>>
>> @@ -492,8 +497,8 @@
>>   /// \param isysroot If non-NULL, the system include path  
>> specified by the
>>   /// user. This is only used with relocatable PCH files. If non- 
>> NULL,
>>   /// a relocatable PCH file will use the default path "/".
>> -      PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
>> -                Diagnostic &Diags, const char *isysroot = 0);
>> +  PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
>> +            Diagnostic &Diags, const char *isysroot = 0);
>>   ~PCHReader();
>>
>>   /// \brief Load the precompiled header designated by the given file
>>
>> Modified: cfe/trunk/lib/Basic/FileManager.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FileManager.cpp?rev=84263&r1=84262&r2=84263&view=diff
>>
>> === 
>> === 
>> === 
>> =====================================================================
>> --- cfe/trunk/lib/Basic/FileManager.cpp (original)
>> +++ cfe/trunk/lib/Basic/FileManager.cpp Fri Oct 16 13:18:30 2009
>> @@ -149,6 +149,41 @@
>>   delete &UniqueFiles;
>>  }
>>
>> +void FileManager::addStatCache(StatSysCallCache *statCache, bool  
>> AtBeginning) {
>> +  assert(statCache && "No stat cache provided?");
>> +  if (AtBeginning || StatCache.get() == 0) {
>> +    statCache->setNextStatCache(StatCache.take());
>> +    StatCache.reset(statCache);
>> +    return;
>> +  }
>> +
>> +  StatSysCallCache *LastCache = StatCache.get();
>> +  while (LastCache->getNextStatCache())
>> +    LastCache = LastCache->getNextStatCache();
>> +
>> +  LastCache->setNextStatCache(statCache);
>> +}
>> +
>> +void FileManager::removeStatCache(StatSysCallCache *statCache) {
>> +  if (!statCache)
>> +    return;
>> +
>> +  if (StatCache.get() == statCache) {
>> +    // This is the first stat cache.
>> +    StatCache.reset(StatCache->takeNextStatCache());
>> +    return;
>> +  }
>> +
>> +  // Find the stat cache in the list.
>> +  StatSysCallCache *PrevCache = StatCache.get();
>> +  while (PrevCache && PrevCache->getNextStatCache() != statCache)
>> +    PrevCache = PrevCache->getNextStatCache();
>> +  if (PrevCache)
>> +    PrevCache->setNextStatCache(statCache->getNextStatCache());
>> +  else
>> +    assert(false && "Stat cache not found for removal");
>> +}
>> +
>>  /// getDirectory - Lookup, cache, and verify the specified  
>> directory.  This
>>  /// returns null if the directory doesn't exist.
>>  ///
>> @@ -290,8 +325,8 @@
>>  }
>>
>>  int MemorizeStatCalls::stat(const char *path, struct stat *buf) {
>> -  int result = ::stat(path, buf);
>> -
>> +  int result = StatSysCallCache::stat(path, buf);
>> +
>>   if (result != 0) {
>>     // Cache failed 'stat' results.
>>     struct stat empty;
>>
>> Modified: cfe/trunk/lib/Frontend/CacheTokens.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CacheTokens.cpp?rev=84263&r1=84262&r2=84263&view=diff
>>
>> === 
>> === 
>> === 
>> =====================================================================
>> --- cfe/trunk/lib/Frontend/CacheTokens.cpp (original)
>> +++ cfe/trunk/lib/Frontend/CacheTokens.cpp Fri Oct 16 13:18:30 2009
>> @@ -516,7 +516,7 @@
>>   ~StatListener() {}
>>
>>   int stat(const char *path, struct stat *buf) {
>> -    int result = ::stat(path, buf);
>> +    int result = StatSysCallCache::stat(path, buf);
>>
>>     if (result != 0) // Failed 'stat'.
>>       PM.insert(path, PTHEntry());
>> @@ -553,7 +553,8 @@
>>   PTHWriter PW(*OS, PP);
>>
>>   // Install the 'stat' system call listener in the FileManager.
>> -  PP.getFileManager().setStatCache(new StatListener(PW.getPM()));
>> +  StatListener *StatCache = new StatListener(PW.getPM());
>> +  PP.getFileManager().addStatCache(StatCache, /*AtBeginning=*/true);
>>
>>   // Lex through the entire file.  This will populate SourceManager  
>> with
>>   // all of the header information.
>> @@ -562,7 +563,7 @@
>>   do { PP.Lex(Tok); } while (Tok.isNot(tok::eof));
>>
>>   // Generate the PTH file.
>> -  PP.getFileManager().setStatCache(0);
>> +  PP.getFileManager().removeStatCache(StatCache);
>>   PW.GeneratePTH(&MainFileName);
>>  }
>>
>>
>> Modified: cfe/trunk/lib/Frontend/GeneratePCH.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/GeneratePCH.cpp?rev=84263&r1=84262&r2=84263&view=diff
>>
>> === 
>> === 
>> === 
>> =====================================================================
>> --- cfe/trunk/lib/Frontend/GeneratePCH.cpp (original)
>> +++ cfe/trunk/lib/Frontend/GeneratePCH.cpp Fri Oct 16 13:18:30 2009
>> @@ -53,7 +53,7 @@
>>   // Install a stat() listener to keep track of all of the stat()
>>   // calls.
>>   StatCalls = new MemorizeStatCalls;
>> -  PP.getFileManager().setStatCache(StatCalls);
>> +  PP.getFileManager().addStatCache(StatCalls, /*AtBeginning=*/true);
>>  }
>>
>>  void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
>>
>> Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=84263&r1=84262&r2=84263&view=diff
>>
>> === 
>> === 
>> === 
>> =====================================================================
>> --- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
>> +++ cfe/trunk/lib/Frontend/PCHReader.cpp Fri Oct 16 13:18:30 2009
>> @@ -335,8 +335,6 @@
>>   PP.setCounterValue(Value);
>>  }
>>
>> -
>> -
>>  // 
>> === 
>> --- 
>> ------------------------------------------------------------------- 
>> ===//
>>  // PCH reader implementation
>>  // 
>> === 
>> --- 
>> ------------------------------------------------------------------- 
>> ===//
>> @@ -345,7 +343,7 @@
>>                      const char *isysroot)
>>   : Listener(new PCHValidator(PP, *this)), SourceMgr 
>> (PP.getSourceManager()),
>>     FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
>> -    SemaObj(0), PP(&PP), Context(Context), Consumer(0),
>> +    SemaObj(0), PP(&PP), Context(Context), StatCache(0), Consumer 
>> (0),
>>     IdentifierTableData(0), IdentifierLookupTable(0),
>>     IdentifierOffsets(0),
>>     MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
>> @@ -362,7 +360,7 @@
>>  PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
>>                      Diagnostic &Diags, const char *isysroot)
>>   : SourceMgr(SourceMgr), FileMgr(FileMgr), Diags(Diags),
>> -    SemaObj(0), PP(0), Context(0), Consumer(0),
>> +    SemaObj(0), PP(0), Context(0), StatCache(0), Consumer(0),
>>     IdentifierTableData(0), IdentifierLookupTable(0),
>>     IdentifierOffsets(0),
>>     MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
>> @@ -794,7 +792,7 @@
>>     // If we don't get a hit in the PCH file just forward to 'stat'.
>>     if (I == Cache->end()) {
>>       ++NumStatMisses;
>> -      return ::stat(path, buf);
>> +      return StatSysCallCache::stat(path, buf);
>>     }
>>
>>     ++NumStatHits;
>> @@ -1352,13 +1350,16 @@
>>       }
>>       break;
>>
>> -    case pch::STAT_CACHE:
>> -      FileMgr.setStatCache(
>> -                  new PCHStatCache((const unsigned char *) 
>> BlobStart + Record[0],
>> -                                   (const unsigned char *)BlobStart,
>> -                                   NumStatHits, NumStatMisses));
>> +    case pch::STAT_CACHE: {
>> +      PCHStatCache *MyStatCache =
>> +        new PCHStatCache((const unsigned char *)BlobStart + Record 
>> [0],
>> +                         (const unsigned char *)BlobStart,
>> +                         NumStatHits, NumStatMisses);
>> +      FileMgr.addStatCache(MyStatCache);
>> +      StatCache = MyStatCache;
>>       break;
>> -
>> +    }
>> +
>>     case pch::EXT_VECTOR_DECLS:
>>       if (!ExtVectorDecls.empty()) {
>>         Error("duplicate EXT_VECTOR_DECLS record in PCH file");
>> @@ -1466,7 +1467,8 @@
>>         SourceMgr.ClearPreallocatedSLocEntries();
>>
>>         // Remove the stat cache.
>> -        FileMgr.setStatCache(0);
>> +        if (StatCache)
>> +          FileMgr.removeStatCache((PCHStatCache*)StatCache);
>>
>>         return IgnorePCH;
>>       }
>>
>> Modified: cfe/trunk/lib/Lex/PTHLexer.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PTHLexer.cpp?rev=84263&r1=84262&r2=84263&view=diff
>>
>> === 
>> === 
>> === 
>> =====================================================================
>> --- cfe/trunk/lib/Lex/PTHLexer.cpp (original)
>> +++ cfe/trunk/lib/Lex/PTHLexer.cpp Fri Oct 16 13:18:30 2009
>> @@ -679,7 +679,8 @@
>>     CacheTy::iterator I = Cache.find(path);
>>
>>     // If we don't get a hit in the PTH file just forward to 'stat'.
>> -    if (I == Cache.end()) return ::stat(path, buf);
>> +    if (I == Cache.end())
>> +      return StatSysCallCache::stat(path, buf);
>>
>>     const PTHStatData& Data = *I;
>>
>>
>> Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=84263&r1=84262&r2=84263&view=diff
>>
>> ====



More information about the cfe-commits mailing list