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
|
||||
/// to process when doing quick skipping of preprocessor blocks.
|
||||
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
|
||||
void operator=(const PTHLexer&); // DO NOT IMPLEMENT
|
||||
|
@ -57,7 +64,8 @@ public:
|
|||
|
||||
/// Create a PTHLexer for the specified token stream.
|
||||
PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D,
|
||||
const char* ppcond, PTHManager& PM);
|
||||
const char* ppcond, const char* spellingTable, unsigned numSpellings,
|
||||
PTHManager& PM);
|
||||
|
||||
~PTHLexer() {}
|
||||
|
||||
|
|
|
@ -69,6 +69,10 @@ class PTHManager {
|
|||
/// GetIdentifierInfo - Used by PTHManager to reconstruct IdentifierInfo
|
||||
/// objects from the PTH file.
|
||||
IdentifierInfo* GetIdentifierInfo(unsigned);
|
||||
|
||||
/// GetSpelling - Used by PTHLexer classes to get the cached spelling
|
||||
/// for a token.
|
||||
unsigned GetSpelling(unsigned PTHOffset, const char*& Buffer);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -49,9 +49,13 @@ static inline uint32_t Read32(const char*& data) {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
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),
|
||||
PPCond(ppcond), CurPPCondPtr(ppcond), PTHMgr(PM) {}
|
||||
PPCond(ppcond), CurPPCondPtr(ppcond),
|
||||
SpellingTable(spellingTable), SpellingsLeft(NumSpellings),
|
||||
PTHMgr(PM) {}
|
||||
|
||||
void PTHLexer::Lex(Token& Tok) {
|
||||
LexNextToken:
|
||||
|
@ -285,8 +289,55 @@ SourceLocation PTHLexer::getSourceLocation() {
|
|||
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) {
|
||||
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();
|
||||
uint32_t len = Read32(ppcond);
|
||||
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());
|
||||
return new PTHLexer(PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
|
||||
*this);
|
||||
spellingTable, len, *this);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue