From 3ed42cb0b3705eae3d54224d068a7a0970c3c2f9 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sat, 11 Apr 2009 00:14:32 +0000 Subject: Store unique IDs for identifiers in the PCH file. Use some bitmangling so that we only need to perform the lookup and identifier resolution once per identifier in the PCH file. llvm-svn: 68846 --- clang/lib/Frontend/PCHWriter.cpp | 65 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 5 deletions(-) (limited to 'clang/lib/Frontend/PCHWriter.cpp') diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 4963ea11608..3c795bf722a 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -818,6 +818,55 @@ void PCHWriter::WriteDeclsBlock(ASTContext &Context) { S.ExitBlock(); } +/// \brief Write the identifier table into the PCH file. +/// +/// The identifier table consists of a blob containing string data +/// (the actual identifiers themselves) and a separate "offsets" index +/// that maps identifier IDs to locations within the blob. +void PCHWriter::WriteIdentifierTable() { + using namespace llvm; + + // Create and write out the blob that contains the identifier + // strings. + RecordData IdentOffsets; + IdentOffsets.resize(IdentifierIDs.size()); + { + // Create the identifier string data. + std::vector Data; + Data.push_back(0); // Data must not be empty. + for (llvm::DenseMap::iterator + ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end(); + ID != IDEnd; ++ID) { + assert(ID->first && "NULL identifier in identifier table"); + + // Make sure we're starting on an odd byte. The PCH reader + // expects the low bit to be set on all of the offsets. + if ((Data.size() & 0x01) == 0) + Data.push_back((char)0); + + IdentOffsets[ID->second - 1] = Data.size(); + Data.insert(Data.end(), + ID->first->getName(), + ID->first->getName() + ID->first->getLength()); + Data.push_back((char)0); + } + + // Create a blob abbreviation + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(pch::IDENTIFIER_TABLE)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Triple name + unsigned IDTableAbbrev = S.EmitAbbrev(Abbrev); + + // Write the identifier table + RecordData Record; + Record.push_back(pch::IDENTIFIER_TABLE); + S.EmitRecordWithBlob(IDTableAbbrev, Record, &Data.front(), Data.size()); + } + + // Write the offsets table for identifier IDs. + S.EmitRecord(pch::IDENTIFIER_OFFSET, IdentOffsets); +} + PCHWriter::PCHWriter(llvm::BitstreamWriter &S) : S(S), NextTypeID(pch::NUM_PREDEF_TYPE_IDS) { } @@ -842,6 +891,7 @@ void PCHWriter::WritePCH(ASTContext &Context, const Preprocessor &PP) { WriteDeclsBlock(Context); S.EmitRecord(pch::TYPE_OFFSET, TypeOffsets); S.EmitRecord(pch::DECL_OFFSET, DeclOffsets); + WriteIdentifierTable(); S.ExitBlock(); } @@ -858,11 +908,16 @@ void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) { } void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) { - // FIXME: Emit an identifier ID, not the actual string! - const char *Name = II->getName(); - unsigned Len = strlen(Name); - Record.push_back(Len); - Record.insert(Record.end(), Name, Name + Len); + if (II == 0) { + Record.push_back(0); + return; + } + + pch::IdentID &ID = IdentifierIDs[II]; + if (ID == 0) + ID = IdentifierIDs.size(); + + Record.push_back(ID); } void PCHWriter::AddTypeRef(QualType T, RecordData &Record) { -- cgit v1.2.3