[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