зеркало из https://github.com/microsoft/clang-1.git
When chaining, only write interesting selectors to the PCH.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110229 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
5d05007b7a
Коммит
e58aa890e8
|
@ -675,16 +675,21 @@ public:
|
||||||
return static_cast<unsigned>(IdentifiersLoaded.size());
|
return static_cast<unsigned>(IdentifiersLoaded.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Returns the number of types found in this file.
|
/// \brief Returns the number of types found in the chain.
|
||||||
unsigned getTotalNumTypes() const {
|
unsigned getTotalNumTypes() const {
|
||||||
return static_cast<unsigned>(TypesLoaded.size());
|
return static_cast<unsigned>(TypesLoaded.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Returns the number of declarations found in this file.
|
/// \brief Returns the number of declarations found in the chain.
|
||||||
unsigned getTotalNumDecls() const {
|
unsigned getTotalNumDecls() const {
|
||||||
return static_cast<unsigned>(DeclsLoaded.size());
|
return static_cast<unsigned>(DeclsLoaded.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the number of selectors found in the chain.
|
||||||
|
unsigned getTotalNumSelectors() const {
|
||||||
|
return static_cast<unsigned>(SelectorsLoaded.size());
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Reads a TemplateArgumentLocInfo appropriate for the
|
/// \brief Reads a TemplateArgumentLocInfo appropriate for the
|
||||||
/// given TemplateArgument kind.
|
/// given TemplateArgument kind.
|
||||||
TemplateArgumentLocInfo
|
TemplateArgumentLocInfo
|
||||||
|
@ -794,6 +799,9 @@ public:
|
||||||
virtual std::pair<ObjCMethodList, ObjCMethodList>
|
virtual std::pair<ObjCMethodList, ObjCMethodList>
|
||||||
ReadMethodPool(Selector Sel);
|
ReadMethodPool(Selector Sel);
|
||||||
|
|
||||||
|
/// \brief Load a selector from disk, registering its ID if it exists.
|
||||||
|
void LoadSelector(Selector Sel);
|
||||||
|
|
||||||
void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
|
void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
|
||||||
void SetGloballyVisibleDecls(IdentifierInfo *II,
|
void SetGloballyVisibleDecls(IdentifierInfo *II,
|
||||||
const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
|
const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
|
||||||
|
|
|
@ -171,6 +171,12 @@ private:
|
||||||
/// table.
|
/// table.
|
||||||
std::vector<uint32_t> IdentifierOffsets;
|
std::vector<uint32_t> IdentifierOffsets;
|
||||||
|
|
||||||
|
/// \brief The first ID number we can use for our own selectors.
|
||||||
|
pch::SelectorID FirstSelectorID;
|
||||||
|
|
||||||
|
/// \brief The selector ID that will be assigned to the next new identifier.
|
||||||
|
pch::SelectorID NextSelectorID;
|
||||||
|
|
||||||
/// \brief Map that provides the ID numbers of each Selector.
|
/// \brief Map that provides the ID numbers of each Selector.
|
||||||
llvm::DenseMap<Selector, pch::SelectorID> SelectorIDs;
|
llvm::DenseMap<Selector, pch::SelectorID> SelectorIDs;
|
||||||
|
|
||||||
|
|
|
@ -3230,6 +3230,11 @@ PCHReader::ReadMethodPool(Selector Sel) {
|
||||||
return std::make_pair(Data.Instance, Data.Factory);
|
return std::make_pair(Data.Instance, Data.Factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PCHReader::LoadSelector(Selector Sel) {
|
||||||
|
// It would be complicated to avoid reading the methods anyway. So don't.
|
||||||
|
ReadMethodPool(Sel);
|
||||||
|
}
|
||||||
|
|
||||||
void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
|
void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
|
||||||
assert(ID && "Non-zero identifier ID required");
|
assert(ID && "Non-zero identifier ID required");
|
||||||
assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
|
assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
|
||||||
|
|
|
@ -1655,13 +1655,14 @@ void PCHWriter::WriteSelectors(Sema &SemaRef) {
|
||||||
// Do we have to do anything at all?
|
// Do we have to do anything at all?
|
||||||
if (SemaRef.MethodPool.empty() && SelectorIDs.empty())
|
if (SemaRef.MethodPool.empty() && SelectorIDs.empty())
|
||||||
return;
|
return;
|
||||||
|
unsigned NumTableEntries = 0;
|
||||||
// Create and write out the blob that contains selectors and the method pool.
|
// Create and write out the blob that contains selectors and the method pool.
|
||||||
{
|
{
|
||||||
OnDiskChainedHashTableGenerator<PCHMethodPoolTrait> Generator;
|
OnDiskChainedHashTableGenerator<PCHMethodPoolTrait> Generator;
|
||||||
|
|
||||||
// Create the on-disk hash table representation. We walk through every
|
// Create the on-disk hash table representation. We walk through every
|
||||||
// selector we've seen and look it up in the method pool.
|
// selector we've seen and look it up in the method pool.
|
||||||
SelectorOffsets.resize(SelectorIDs.size());
|
SelectorOffsets.resize(NextSelectorID - FirstSelectorID);
|
||||||
for (llvm::DenseMap<Selector, pch::SelectorID>::iterator
|
for (llvm::DenseMap<Selector, pch::SelectorID>::iterator
|
||||||
I = SelectorIDs.begin(), E = SelectorIDs.end();
|
I = SelectorIDs.begin(), E = SelectorIDs.end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
|
@ -1676,7 +1677,26 @@ void PCHWriter::WriteSelectors(Sema &SemaRef) {
|
||||||
Data.Instance = F->second.first;
|
Data.Instance = F->second.first;
|
||||||
Data.Factory = F->second.second;
|
Data.Factory = F->second.second;
|
||||||
}
|
}
|
||||||
|
// Only write this selector if it's not in an existing PCH or something
|
||||||
|
// changed.
|
||||||
|
if (Chain && I->second < FirstSelectorID) {
|
||||||
|
// Selector already exists. Did it change?
|
||||||
|
bool changed = false;
|
||||||
|
for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method;
|
||||||
|
M = M->Next) {
|
||||||
|
if (M->Method->getPCHLevel() == 0)
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method;
|
||||||
|
M = M->Next) {
|
||||||
|
if (M->Method->getPCHLevel() == 0)
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (!changed)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Generator.insert(S, Data);
|
Generator.insert(S, Data);
|
||||||
|
++NumTableEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the on-disk hash table in a buffer.
|
// Create the on-disk hash table in a buffer.
|
||||||
|
@ -1702,7 +1722,7 @@ void PCHWriter::WriteSelectors(Sema &SemaRef) {
|
||||||
RecordData Record;
|
RecordData Record;
|
||||||
Record.push_back(pch::METHOD_POOL);
|
Record.push_back(pch::METHOD_POOL);
|
||||||
Record.push_back(BucketOffset);
|
Record.push_back(BucketOffset);
|
||||||
Record.push_back(SelectorIDs.size());
|
Record.push_back(NumTableEntries);
|
||||||
Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str());
|
Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str());
|
||||||
|
|
||||||
// Create a blob abbreviation for the selector table offsets.
|
// Create a blob abbreviation for the selector table offsets.
|
||||||
|
@ -2115,17 +2135,20 @@ void PCHWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
|
||||||
void PCHWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
|
void PCHWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
|
||||||
unsigned ID = SelectorIDs[Sel];
|
unsigned ID = SelectorIDs[Sel];
|
||||||
assert(ID && "Unknown selector");
|
assert(ID && "Unknown selector");
|
||||||
SelectorOffsets[ID - 1] = Offset;
|
// Don't record offsets for selectors that are also available in a different
|
||||||
|
// file.
|
||||||
|
if (ID < FirstSelectorID)
|
||||||
|
return;
|
||||||
|
SelectorOffsets[ID - FirstSelectorID] = Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
|
PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
|
||||||
: Stream(Stream), Chain(0), FirstDeclID(1),
|
: Stream(Stream), Chain(0), FirstDeclID(1), NextDeclID(FirstDeclID),
|
||||||
FirstTypeID(pch::NUM_PREDEF_TYPE_IDS), FirstIdentID(1),
|
FirstTypeID(pch::NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
|
||||||
CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0),
|
FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1),
|
||||||
NumLexicalDeclContexts(0), NumVisibleDeclContexts(0) {
|
NextSelectorID(FirstSelectorID), CollectedStmts(&StmtsToEmit),
|
||||||
NextDeclID = FirstDeclID;
|
NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
|
||||||
NextTypeID = FirstTypeID;
|
NumVisibleDeclContexts(0) {
|
||||||
NextIdentID = FirstIdentID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
|
void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
|
||||||
|
@ -2321,9 +2344,11 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
|
||||||
FirstDeclID += Chain->getTotalNumDecls();
|
FirstDeclID += Chain->getTotalNumDecls();
|
||||||
FirstTypeID += Chain->getTotalNumTypes();
|
FirstTypeID += Chain->getTotalNumTypes();
|
||||||
FirstIdentID += Chain->getTotalNumIdentifiers();
|
FirstIdentID += Chain->getTotalNumIdentifiers();
|
||||||
|
FirstSelectorID += Chain->getTotalNumSelectors();
|
||||||
NextDeclID = FirstDeclID;
|
NextDeclID = FirstDeclID;
|
||||||
NextTypeID = FirstTypeID;
|
NextTypeID = FirstTypeID;
|
||||||
NextIdentID = FirstIdentID;
|
NextIdentID = FirstIdentID;
|
||||||
|
NextSelectorID = FirstSelectorID;
|
||||||
|
|
||||||
ASTContext &Context = SemaRef.Context;
|
ASTContext &Context = SemaRef.Context;
|
||||||
Preprocessor &PP = SemaRef.PP;
|
Preprocessor &PP = SemaRef.PP;
|
||||||
|
@ -2519,8 +2544,13 @@ pch::SelectorID PCHWriter::getSelectorRef(Selector Sel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pch::SelectorID &SID = SelectorIDs[Sel];
|
pch::SelectorID &SID = SelectorIDs[Sel];
|
||||||
|
if (SID == 0 && Chain) {
|
||||||
|
// This might trigger a ReadSelector callback, which will set the ID for
|
||||||
|
// this selector.
|
||||||
|
Chain->LoadSelector(Sel);
|
||||||
|
}
|
||||||
if (SID == 0) {
|
if (SID == 0) {
|
||||||
SID = SelectorIDs.size();
|
SID = NextSelectorID++;
|
||||||
}
|
}
|
||||||
return SID;
|
return SID;
|
||||||
}
|
}
|
||||||
|
@ -2875,6 +2905,7 @@ void PCHWriter::SetReader(PCHReader *Reader) {
|
||||||
assert(FirstDeclID == NextDeclID &&
|
assert(FirstDeclID == NextDeclID &&
|
||||||
FirstTypeID == NextTypeID &&
|
FirstTypeID == NextTypeID &&
|
||||||
FirstIdentID == NextIdentID &&
|
FirstIdentID == NextIdentID &&
|
||||||
|
FirstSelectorID == NextSelectorID &&
|
||||||
"Setting chain after writing has started.");
|
"Setting chain after writing has started.");
|
||||||
Chain = Reader;
|
Chain = Reader;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче