forked from OSchip/llvm-project
PTH: Hook up getSpelling() caching in PTHLexer. This results in a nice
performance gain. Here's what we see for -Eonly on Cocoa.h (using PTH): - wall time decreases by 21% (26% speedup overall) - system time decreases by 35% - user time decreases by 6% These reductions are due to not paging source files just to get spellings for literals. The solution in place doesn't appear to be 100% yet, as we still see some of the pages for source files getting mapped in. Using -print-stats, we see that SourceManager maps in 7179K less bytes of source text (reduction of 75%). Will investigate why the remaining 25% are getting paged in. With these changes, here's how PTH compares to non-PTH on Cocoa.h: -Eonly: PTH takes 64% of the time as non-PTH (54% speedup) -fsyntax-only: PTH takes 89% of the time as non-PTH (11% speedup) llvm-svn: 61913
This commit is contained in:
parent
145a7cfa85
commit
d5e6e16d0d
|
@ -41,6 +41,13 @@ class PTHLexer : public PreprocessorLexer {
|
||||||
/// CurPPCondPtr - Pointer inside PPCond that refers to the next entry
|
/// CurPPCondPtr - Pointer inside PPCond that refers to the next entry
|
||||||
/// to process when doing quick skipping of preprocessor blocks.
|
/// to process when doing quick skipping of preprocessor blocks.
|
||||||
const char* CurPPCondPtr;
|
const char* CurPPCondPtr;
|
||||||
|
|
||||||
|
/// Pointer to a side table containing offsets in the PTH file
|
||||||
|
/// for token spellings.
|
||||||
|
const char* SpellingTable;
|
||||||
|
|
||||||
|
/// Number of cached spellings left in the cached source file.
|
||||||
|
unsigned SpellingsLeft;
|
||||||
|
|
||||||
PTHLexer(const PTHLexer&); // DO NOT IMPLEMENT
|
PTHLexer(const PTHLexer&); // DO NOT IMPLEMENT
|
||||||
void operator=(const PTHLexer&); // DO NOT IMPLEMENT
|
void operator=(const PTHLexer&); // DO NOT IMPLEMENT
|
||||||
|
@ -57,7 +64,8 @@ public:
|
||||||
|
|
||||||
/// Create a PTHLexer for the specified token stream.
|
/// Create a PTHLexer for the specified token stream.
|
||||||
PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D,
|
PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D,
|
||||||
const char* ppcond, PTHManager& PM);
|
const char* ppcond, const char* spellingTable, unsigned numSpellings,
|
||||||
|
PTHManager& PM);
|
||||||
|
|
||||||
~PTHLexer() {}
|
~PTHLexer() {}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,10 @@ class PTHManager {
|
||||||
/// GetIdentifierInfo - Used by PTHManager to reconstruct IdentifierInfo
|
/// GetIdentifierInfo - Used by PTHManager to reconstruct IdentifierInfo
|
||||||
/// objects from the PTH file.
|
/// objects from the PTH file.
|
||||||
IdentifierInfo* GetIdentifierInfo(unsigned);
|
IdentifierInfo* GetIdentifierInfo(unsigned);
|
||||||
|
|
||||||
|
/// GetSpelling - Used by PTHLexer classes to get the cached spelling
|
||||||
|
/// for a token.
|
||||||
|
unsigned GetSpelling(unsigned PTHOffset, const char*& Buffer);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,13 @@ static inline uint32_t Read32(const char*& data) {
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D,
|
PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D,
|
||||||
const char* ppcond, PTHManager& PM)
|
const char* ppcond,
|
||||||
|
const char* spellingTable, unsigned NumSpellings,
|
||||||
|
PTHManager& PM)
|
||||||
: PreprocessorLexer(&pp, fileloc), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
|
: PreprocessorLexer(&pp, fileloc), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
|
||||||
PPCond(ppcond), CurPPCondPtr(ppcond), PTHMgr(PM) {}
|
PPCond(ppcond), CurPPCondPtr(ppcond),
|
||||||
|
SpellingTable(spellingTable), SpellingsLeft(NumSpellings),
|
||||||
|
PTHMgr(PM) {}
|
||||||
|
|
||||||
void PTHLexer::Lex(Token& Tok) {
|
void PTHLexer::Lex(Token& Tok) {
|
||||||
LexNextToken:
|
LexNextToken:
|
||||||
|
@ -285,8 +289,55 @@ SourceLocation PTHLexer::getSourceLocation() {
|
||||||
return SourceLocation::getFileLoc(FileID, offset);
|
return SourceLocation::getFileLoc(FileID, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned PTHManager::GetSpelling(unsigned PTHOffset, const char *& Buffer) {
|
||||||
|
const char* p = Buf->getBufferStart() + PTHOffset;
|
||||||
|
assert(p < Buf->getBufferEnd());
|
||||||
|
|
||||||
|
// The string is prefixed by 16 bits for its length, followed by the string
|
||||||
|
// itself.
|
||||||
|
unsigned len = ((unsigned) ((uint8_t) p[0]))
|
||||||
|
| (((unsigned) ((uint8_t) p[1])) << 8);
|
||||||
|
|
||||||
|
Buffer = p + 2;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned PTHLexer::getSpelling(SourceLocation sloc, const char *&Buffer) {
|
unsigned PTHLexer::getSpelling(SourceLocation sloc, const char *&Buffer) {
|
||||||
return 0;
|
const char* p = SpellingTable;
|
||||||
|
SourceManager& SM = PP->getSourceManager();
|
||||||
|
unsigned fpos = SM.getFullFilePos(SM.getPhysicalLoc(sloc));
|
||||||
|
unsigned len = 0;
|
||||||
|
|
||||||
|
while (SpellingsLeft) {
|
||||||
|
uint32_t TokOffset =
|
||||||
|
((uint32_t) ((uint8_t) p[0]))
|
||||||
|
| (((uint32_t) ((uint8_t) p[1])) << 8)
|
||||||
|
| (((uint32_t) ((uint8_t) p[2])) << 16)
|
||||||
|
| (((uint32_t) ((uint8_t) p[3])) << 24);
|
||||||
|
|
||||||
|
if (TokOffset > fpos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
--SpellingsLeft;
|
||||||
|
|
||||||
|
// Did we find a matching token offset for this spelling?
|
||||||
|
if (TokOffset == fpos) {
|
||||||
|
uint32_t SpellingPTHOffset =
|
||||||
|
((uint32_t) ((uint8_t) p[4]))
|
||||||
|
| (((uint32_t) ((uint8_t) p[5])) << 8)
|
||||||
|
| (((uint32_t) ((uint8_t) p[6])) << 16)
|
||||||
|
| (((uint32_t) ((uint8_t) p[7])) << 24);
|
||||||
|
|
||||||
|
len = PTHMgr.GetSpelling(SpellingPTHOffset, Buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No match. Keep on looking.
|
||||||
|
p += sizeof(uint32_t)*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellingTable = p;
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -478,8 +529,15 @@ PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
|
||||||
const char* ppcond = Buf->getBufferStart() + FileData.getPPCondOffset();
|
const char* ppcond = Buf->getBufferStart() + FileData.getPPCondOffset();
|
||||||
uint32_t len = Read32(ppcond);
|
uint32_t len = Read32(ppcond);
|
||||||
if (len == 0) ppcond = 0;
|
if (len == 0) ppcond = 0;
|
||||||
|
|
||||||
|
// Get the location of the spelling table.
|
||||||
|
const char* spellingTable = Buf->getBufferStart() +
|
||||||
|
FileData.getSpellingOffset();
|
||||||
|
|
||||||
|
len = Read32(spellingTable);
|
||||||
|
if (len == 0) spellingTable = 0;
|
||||||
|
|
||||||
assert(data < Buf->getBufferEnd());
|
assert(data < Buf->getBufferEnd());
|
||||||
return new PTHLexer(PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
|
return new PTHLexer(PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
|
||||||
*this);
|
spellingTable, len, *this);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue