[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/Preprocessor.cpp test/CMakeLists.txt test/Index/c-index-pch.c test/Index/c-index-pch.h

Ted Kremenek kremenek at apple.com
Fri Oct 16 11:38:12 PDT 2009


Awesome.  Thanks Doug!

On Oct 16, 2009, at 11:18 AM, Douglas Gregor 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.
>
> 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
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
> +++ cfe/trunk/lib/Lex/Preprocessor.cpp Fri Oct 16 13:18:30 2009
> @@ -122,7 +122,7 @@
>
> void Preprocessor::setPTHManager(PTHManager* pm) {
>   PTH.reset(pm);
> -  FileMgr.setStatCache(PTH->createStatCache());
> +  FileMgr.addStatCache(PTH->createStatCache());
> }
>
> void Preprocessor::DumpToken(const Token &Tok, bool DumpFlags) const {
>
> Modified: cfe/trunk/test/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CMakeLists.txt?rev=84263&r1=84262&r2=84263&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/test/CMakeLists.txt (original)
> +++ cfe/trunk/test/CMakeLists.txt Fri Oct 16 13:18:30 2009
> @@ -45,7 +45,7 @@
>                   ${LLVM_SOURCE_DIR}/utils/lit/lit.py
>                   -sv ${CLANG_TEST_EXTRA_ARGS}
>                   ${CMAKE_CURRENT_BINARY_DIR}/${testdir}
> -                  DEPENDS clang clang-cc index-test
> +                  DEPENDS clang clang-cc index-test c-index-test
>                   COMMENT "Running Clang regression tests in $ 
> {testdir}")
>   endforeach()
>
> @@ -62,7 +62,7 @@
>                 ${LLVM_SOURCE_DIR}/utils/lit/lit.py
>                 -sv ${CLANG_TEST_EXTRA_ARGS}
>                 ${CMAKE_CURRENT_BINARY_DIR}
> -                DEPENDS clang clang-cc index-test
> +                DEPENDS clang clang-cc index-test c-index-test
>                 COMMENT "Running Clang regression tests")
>
>   add_custom_target(clang-c++tests
> @@ -78,6 +78,6 @@
>                 ${LLVM_SOURCE_DIR}/utils/lit/lit.py
>                 -sv ${CLANG_TEST_EXTRA_ARGS}
>                 ${CMAKE_CURRENT_SOURCE_DIR}/../utils/C++Tests
> -                DEPENDS clang clang-cc index-test
> +                DEPENDS clang clang-cc index-test c-index-test
>                 COMMENT "Running Clang regression tests")
> endif()
>
> Added: cfe/trunk/test/Index/c-index-pch.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/c-index-pch.c?rev=84263&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/test/Index/c-index-pch.c (added)
> +++ cfe/trunk/test/Index/c-index-pch.c Fri Oct 16 13:18:30 2009
> @@ -0,0 +1,7 @@
> +// RUN: clang-cc -emit-pch -x c -o %t.pch %S/c-index-pch.h &&
> +// RUN: clang-cc -include-pch %t.pch -x c -emit-pch -o %t.ast %s &&
> +// RUN: c-index-test %t.ast all | FileCheck -check-prefix=ALL %s
> +// CHECK-ALL: FunctionDecl=foo
> +// CHECK-ALL: VarDecl=bar
> +// CHECK-ALL: FunctionDecl=wibble
> +void wibble(int i);
>
> Added: cfe/trunk/test/Index/c-index-pch.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/c-index-pch.h?rev=84263&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/test/Index/c-index-pch.h (added)
> +++ cfe/trunk/test/Index/c-index-pch.h Fri Oct 16 13:18:30 2009
> @@ -0,0 +1,7 @@
> +#ifndef C_INDEX_PCH_H
> +#define C_INDEX_PCH_H
> +
> +void foo(int i, float f);
> +extern int bar;
> +
> +#endif // C_INDEX_PCH_H
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list