forked from OSchip/llvm-project
Don't read all of the records in the PCH file's preprocessor block,
most of which are ignored. Instead, move the __COUNTER__ value out to a PCH-level record (since it is handled eagerly) and move the header file information into the SourceManager block (which is also, currently, loaded eagerly). This results in another 17% performance improvement in the Cocoa-prefixed "Hello, World" with PCH. llvm-svn: 70097
This commit is contained in:
parent
ab2784f2c1
commit
eda6a89c4e
|
|
@ -169,7 +169,11 @@ namespace clang {
|
|||
SELECTOR_OFFSETS = 12,
|
||||
|
||||
/// \brief Record code for the Objective-C method pool,
|
||||
METHOD_POOL = 13
|
||||
METHOD_POOL = 13,
|
||||
|
||||
/// \brief The value of the next __COUNTER__ to dispense.
|
||||
/// [PP_COUNTER_VALUE, Val]
|
||||
PP_COUNTER_VALUE = 14
|
||||
};
|
||||
|
||||
/// \brief Record types used within a source manager block.
|
||||
|
|
@ -189,7 +193,10 @@ namespace clang {
|
|||
SM_SLOC_INSTANTIATION_ENTRY = 4,
|
||||
/// \brief Describes the SourceManager's line table, with
|
||||
/// information about #line directives.
|
||||
SM_LINE_TABLE = 5
|
||||
SM_LINE_TABLE = 5,
|
||||
/// \brief Describes one header file info [isImport, DirInfo, NumIncludes]
|
||||
/// ControllingMacro is optional.
|
||||
SM_HEADER_FILE_INFO = 6
|
||||
};
|
||||
|
||||
/// \brief Record types used within a preprocessor block.
|
||||
|
|
@ -208,15 +215,7 @@ namespace clang {
|
|||
|
||||
/// \brief Describes one token.
|
||||
/// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
|
||||
PP_TOKEN = 3,
|
||||
|
||||
/// \brief The value of the next __COUNTER__ to dispense.
|
||||
/// [PP_COUNTER_VALUE, Val]
|
||||
PP_COUNTER_VALUE = 4,
|
||||
|
||||
/// \brief Describes one header file info [isImport, DirInfo, NumIncludes]
|
||||
/// ControlloingMacro is optional.
|
||||
PP_HEADER_FILE_INFO = 5
|
||||
PP_TOKEN = 3
|
||||
};
|
||||
|
||||
/// \defgroup PCHAST Precompiled header AST constants
|
||||
|
|
|
|||
|
|
@ -245,12 +245,11 @@ private:
|
|||
/// Objective-C protocols.
|
||||
llvm::SmallVector<Decl *, 16> InterestingDecls;
|
||||
|
||||
PCHReadResult ReadPCHBlock(uint64_t &PreprocessorBlockOffset);
|
||||
PCHReadResult ReadPCHBlock();
|
||||
bool CheckPredefinesBuffer(const char *PCHPredef,
|
||||
unsigned PCHPredefLen,
|
||||
FileID PCHBufferID);
|
||||
PCHReadResult ReadSourceManagerBlock();
|
||||
bool ReadPreprocessorBlock();
|
||||
|
||||
bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record);
|
||||
QualType ReadTypeRecord(uint64_t Offset);
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ private:
|
|||
|
||||
void WriteTargetTriple(const TargetInfo &Target);
|
||||
void WriteLanguageOptions(const LangOptions &LangOpts);
|
||||
void WriteSourceManagerBlock(SourceManager &SourceMgr);
|
||||
void WriteSourceManagerBlock(SourceManager &SourceMgr,
|
||||
const Preprocessor &PP);
|
||||
void WritePreprocessor(const Preprocessor &PP);
|
||||
void WriteType(const Type *T);
|
||||
void WriteTypesBlock(ASTContext &Context);
|
||||
|
|
|
|||
|
|
@ -1473,6 +1473,7 @@ PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
|
|||
|
||||
SourceManager &SourceMgr = Context.getSourceManager();
|
||||
RecordData Record;
|
||||
unsigned NumHeaderInfos = 0;
|
||||
while (true) {
|
||||
unsigned Code = Stream.ReadCode();
|
||||
if (Code == llvm::bitc::END_BLOCK) {
|
||||
|
|
@ -1557,6 +1558,16 @@ PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
|
|||
if (ParseLineTable(SourceMgr, Record))
|
||||
return Failure;
|
||||
break;
|
||||
|
||||
case pch::SM_HEADER_FILE_INFO: {
|
||||
HeaderFileInfo HFI;
|
||||
HFI.isImport = Record[0];
|
||||
HFI.DirInfo = Record[1];
|
||||
HFI.NumIncludes = Record[2];
|
||||
HFI.ControllingMacroID = Record[3];
|
||||
PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1597,10 +1608,6 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {
|
|||
pch::PreprocessorRecordTypes RecType =
|
||||
(pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
|
||||
switch (RecType) {
|
||||
case pch::PP_COUNTER_VALUE:
|
||||
// Skip this record.
|
||||
break;
|
||||
|
||||
case pch::PP_MACRO_OBJECT_LIKE:
|
||||
case pch::PP_MACRO_FUNCTION_LIKE: {
|
||||
// If we already have a macro, that means that we've hit the end
|
||||
|
|
@ -1663,70 +1670,12 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {
|
|||
Macro->AddTokenToBody(Tok);
|
||||
break;
|
||||
}
|
||||
case pch::PP_HEADER_FILE_INFO:
|
||||
break; // Already processed by ReadPreprocessorBlock().
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PCHReader::ReadPreprocessorBlock() {
|
||||
if (Stream.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID))
|
||||
return Error("Malformed preprocessor block record");
|
||||
|
||||
RecordData Record;
|
||||
unsigned NumHeaderInfos = 0;
|
||||
while (true) {
|
||||
unsigned Code = Stream.ReadCode();
|
||||
switch (Code) {
|
||||
case llvm::bitc::END_BLOCK:
|
||||
if (Stream.ReadBlockEnd())
|
||||
return Error("Error at end of preprocessor block");
|
||||
return false;
|
||||
|
||||
case llvm::bitc::ENTER_SUBBLOCK:
|
||||
// No known subblocks, always skip them.
|
||||
Stream.ReadSubBlockID();
|
||||
if (Stream.SkipBlock())
|
||||
return Error("Malformed block record");
|
||||
continue;
|
||||
|
||||
case llvm::bitc::DEFINE_ABBREV:
|
||||
Stream.ReadAbbrevRecord();
|
||||
continue;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Read a record.
|
||||
Record.clear();
|
||||
pch::PreprocessorRecordTypes RecType =
|
||||
(pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
|
||||
switch (RecType) {
|
||||
default: // Default behavior: ignore unknown records.
|
||||
break;
|
||||
case pch::PP_COUNTER_VALUE:
|
||||
if (!Record.empty())
|
||||
PP.setCounterValue(Record[0]);
|
||||
break;
|
||||
|
||||
case pch::PP_MACRO_OBJECT_LIKE:
|
||||
case pch::PP_MACRO_FUNCTION_LIKE:
|
||||
case pch::PP_TOKEN:
|
||||
break;
|
||||
case pch::PP_HEADER_FILE_INFO: {
|
||||
HeaderFileInfo HFI;
|
||||
HFI.isImport = Record[0];
|
||||
HFI.DirInfo = Record[1];
|
||||
HFI.NumIncludes = Record[2];
|
||||
HFI.ControllingMacroID = Record[3];
|
||||
PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PCHReader::PCHReadResult
|
||||
PCHReader::ReadPCHBlock(uint64_t &PreprocessorBlockOffset) {
|
||||
PCHReader::ReadPCHBlock() {
|
||||
if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
|
||||
Error("Malformed block record");
|
||||
return Failure;
|
||||
|
|
@ -1757,13 +1706,6 @@ PCHReader::ReadPCHBlock(uint64_t &PreprocessorBlockOffset) {
|
|||
break;
|
||||
|
||||
case pch::PREPROCESSOR_BLOCK_ID:
|
||||
// Skip the preprocessor block for now, but remember where it is. We
|
||||
// want to read it in after the identifier table.
|
||||
if (PreprocessorBlockOffset) {
|
||||
Error("Multiple preprocessor blocks found.");
|
||||
return Failure;
|
||||
}
|
||||
PreprocessorBlockOffset = Stream.GetCurrentBitNo();
|
||||
if (Stream.SkipBlock()) {
|
||||
Error("Malformed block record");
|
||||
return Failure;
|
||||
|
|
@ -1907,6 +1849,11 @@ PCHReader::ReadPCHBlock(uint64_t &PreprocessorBlockOffset) {
|
|||
PCHMethodPoolLookupTrait(*this));
|
||||
TotalSelectorsInMethodPool = Record[1];
|
||||
break;
|
||||
|
||||
case pch::PP_COUNTER_VALUE:
|
||||
if (!Record.empty())
|
||||
PP.setCounterValue(Record[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Error("Premature end of bitstream");
|
||||
|
|
@ -1938,10 +1885,6 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
|
|||
return IgnorePCH;
|
||||
}
|
||||
|
||||
// We expect a number of well-defined blocks, though we don't necessarily
|
||||
// need to understand them all.
|
||||
uint64_t PreprocessorBlockOffset = 0;
|
||||
|
||||
while (!Stream.AtEndOfStream()) {
|
||||
unsigned Code = Stream.ReadCode();
|
||||
|
||||
|
|
@ -1961,7 +1904,7 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
|
|||
}
|
||||
break;
|
||||
case pch::PCH_BLOCK_ID:
|
||||
switch (ReadPCHBlock(PreprocessorBlockOffset)) {
|
||||
switch (ReadPCHBlock()) {
|
||||
case Success:
|
||||
break;
|
||||
|
||||
|
|
@ -2036,15 +1979,6 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
|
|||
if (unsigned FastEnum
|
||||
= SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
|
||||
Context.setObjCFastEnumerationStateType(GetType(FastEnum));
|
||||
// If we saw the preprocessor block, read it now.
|
||||
if (PreprocessorBlockOffset) {
|
||||
SavedStreamPosition SavedPos(Stream);
|
||||
Stream.JumpToBit(PreprocessorBlockOffset);
|
||||
if (ReadPreprocessorBlock()) {
|
||||
Error("Malformed preprocessor block");
|
||||
return Failure;
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1359,7 +1359,8 @@ static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) {
|
|||
/// entries for files that we actually need. In the common case (no
|
||||
/// errors), we probably won't have to create file entries for any of
|
||||
/// the files in the AST.
|
||||
void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr) {
|
||||
void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
|
||||
const Preprocessor &PP) {
|
||||
// Enter the source manager block.
|
||||
Stream.EnterSubblock(pch::SOURCE_MANAGER_BLOCK_ID, 3);
|
||||
|
||||
|
|
@ -1481,6 +1482,22 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr) {
|
|||
}
|
||||
}
|
||||
|
||||
// Loop over all the header files.
|
||||
HeaderSearch &HS = PP.getHeaderSearchInfo();
|
||||
for (HeaderSearch::header_file_iterator I = HS.header_file_begin(),
|
||||
E = HS.header_file_end();
|
||||
I != E; ++I) {
|
||||
Record.push_back(I->isImport);
|
||||
Record.push_back(I->DirInfo);
|
||||
Record.push_back(I->NumIncludes);
|
||||
if (I->ControllingMacro)
|
||||
AddIdentifierRef(I->ControllingMacro, Record);
|
||||
else
|
||||
Record.push_back(0);
|
||||
Stream.EmitRecord(pch::SM_HEADER_FILE_INFO, Record);
|
||||
Record.clear();
|
||||
}
|
||||
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
|
|
@ -1488,14 +1505,6 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr) {
|
|||
/// preprocessor.
|
||||
///
|
||||
void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
|
||||
// Enter the preprocessor block.
|
||||
Stream.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 2);
|
||||
|
||||
// If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
|
||||
// FIXME: use diagnostics subsystem for localization etc.
|
||||
if (PP.SawDateOrTime())
|
||||
fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
|
||||
|
||||
RecordData Record;
|
||||
|
||||
// If the preprocessor __COUNTER__ value has been bumped, remember it.
|
||||
|
|
@ -1503,8 +1512,16 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
|
|||
Record.push_back(PP.getCounterValue());
|
||||
Stream.EmitRecord(pch::PP_COUNTER_VALUE, Record);
|
||||
Record.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Enter the preprocessor block.
|
||||
Stream.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 2);
|
||||
|
||||
// If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
|
||||
// FIXME: use diagnostics subsystem for localization etc.
|
||||
if (PP.SawDateOrTime())
|
||||
fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
|
||||
|
||||
// Loop over all the macro definitions that are live at the end of the file,
|
||||
// emitting each to the PP section.
|
||||
for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
|
||||
|
|
@ -1564,22 +1581,6 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
|
|||
}
|
||||
++NumMacros;
|
||||
}
|
||||
|
||||
// Loop over all the header files.
|
||||
HeaderSearch &HS = PP.getHeaderSearchInfo();
|
||||
for (HeaderSearch::header_file_iterator I = HS.header_file_begin(),
|
||||
E = HS.header_file_end();
|
||||
I != E; ++I) {
|
||||
Record.push_back(I->isImport);
|
||||
Record.push_back(I->DirInfo);
|
||||
Record.push_back(I->NumIncludes);
|
||||
if (I->ControllingMacro)
|
||||
AddIdentifierRef(I->ControllingMacro, Record);
|
||||
else
|
||||
Record.push_back(0);
|
||||
Stream.EmitRecord(pch::PP_HEADER_FILE_INFO, Record);
|
||||
Record.clear();
|
||||
}
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
|
|
@ -2365,7 +2366,7 @@ void PCHWriter::WritePCH(Sema &SemaRef) {
|
|||
Stream.EnterSubblock(pch::PCH_BLOCK_ID, 4);
|
||||
WriteTargetTriple(Context.Target);
|
||||
WriteLanguageOptions(Context.getLangOptions());
|
||||
WriteSourceManagerBlock(Context.getSourceManager());
|
||||
WriteSourceManagerBlock(Context.getSourceManager(), PP);
|
||||
WritePreprocessor(PP);
|
||||
WriteTypesBlock(Context);
|
||||
WriteDeclsBlock(Context);
|
||||
|
|
|
|||
Loading…
Reference in New Issue