Skip to content

[do not merge] [runtime-cxxmodules] Rework our lazy template specialization deserialization mechanism #14495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions core/dictgen/src/Scanner.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ inline static bool IsElementPresent(const std::vector<const T*> &v, T *el){
using namespace ROOT;
using namespace clang;

extern cling::Interpreter *gInterp;

const char* RScanner::fgClangDeclKey = "ClangDecl"; // property key used for connection with Clang objects
const char* RScanner::fgClangFuncKey = "ClangFunc"; // property key for demangled names

Expand Down Expand Up @@ -1054,6 +1052,8 @@ void RScanner::Scan(const clang::ASTContext &C)
std::cout<<"File name detected"<<std::endl;
}

cling::Interpreter::PushTransactionRAII RAII(const_cast<cling::Interpreter*>(&fInterpreter));

if (fScanType == EScanType::kTwoPasses)
TraverseDecl(C.getTranslationUnitDecl());

Expand Down
10 changes: 10 additions & 0 deletions interpreter/cling/lib/Interpreter/InterpreterCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,16 @@ namespace cling {
return m_Source->FindExternalVisibleDeclsByName(DC, Name);
}

void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override {
m_Source->LoadExternalSpecializations(D, OnlyPartial);
}

bool
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs) override {
return m_Source->LoadExternalSpecializations(D, TemplateArgs);
}

virtual void completeVisibleDeclsMap(const DeclContext* DC) override {
m_Source->completeVisibleDeclsMap(DC);
}
Expand Down
41 changes: 9 additions & 32 deletions interpreter/llvm-project/clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,14 @@ class TemplateArgumentList final
/// stack object. It does not own its template arguments.
enum OnStackType { OnStack };

/// Create stable hash for the given arguments across compiler invocations.
static unsigned ComputeStableHash(ArrayRef<TemplateArgument> Args);

/// Create a new template argument list that copies the given set of
/// template arguments.
static TemplateArgumentList *CreateCopy(ASTContext &Context,
ArrayRef<TemplateArgument> Args);

/// \brief Create hash for the given arguments.
static unsigned ComputeODRHash(ArrayRef<TemplateArgument> Args);

/// Construct a new, temporary template argument list on the stack.
///
/// The template argument list does not own the template arguments
Expand Down Expand Up @@ -780,25 +780,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
}

void anchor() override;
struct LazySpecializationInfo {
uint32_t DeclID = ~0U;
unsigned ODRHash = ~0U;
bool IsPartial = false;
LazySpecializationInfo(uint32_t ID, unsigned Hash = ~0U,
bool Partial = false)
: DeclID(ID), ODRHash(Hash), IsPartial(Partial) { }
LazySpecializationInfo() { }
bool operator<(const LazySpecializationInfo &Other) const {
return DeclID < Other.DeclID;
}
bool operator==(const LazySpecializationInfo &Other) const {
assert((DeclID != Other.DeclID || ODRHash == Other.ODRHash) &&
"Hashes differ!");
assert((DeclID != Other.DeclID || IsPartial == Other.IsPartial) &&
"Both must be the same kinds!");
return DeclID == Other.DeclID;
}
};

protected:
template <typename EntryType> struct SpecEntryTraits {
Expand Down Expand Up @@ -842,16 +823,19 @@ class RedeclarableTemplateDecl : public TemplateDecl,

void loadLazySpecializationsImpl(bool OnlyPartial = false) const;

void loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
bool loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
TemplateParameterList *TPL = nullptr) const;

Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const;

template <class EntryType, typename ...ProfileArguments>
typename SpecEntryTraits<EntryType>::DeclType*
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
void *&InsertPos, ProfileArguments &&...ProfileArgs);

template <class EntryType, typename ...ProfileArguments>
typename SpecEntryTraits<EntryType>::DeclType*
findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
void *&InsertPos, ProfileArguments &&...ProfileArgs);

template <class Derived, class EntryType>
void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
EntryType *Entry, void *InsertPos);
Expand All @@ -867,13 +851,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
InstantiatedFromMember;

/// If non-null, points to an array of specializations (including
/// partial specializations) known only by their external declaration IDs.
///
/// The first value in the array is the number of specializations/partial
/// specializations that follow.
LazySpecializationInfo *LazySpecializations = nullptr;

/// The set of "injected" template arguments used within this
/// template.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,19 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
virtual bool
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);

/// Load all the external specializations for the Decl \param D if \param
/// OnlyPartial is false. Otherwise, load all the external **partial**
/// specializations for the \param D.
virtual void LoadExternalSpecializations(const Decl *D, bool OnlyPartial);

/// Load all the specializations for the Decl \param D with the same template
/// args specified by \param TemplateArgs.
///
/// Return true if any external specialization loaded. Return false otherwise.
virtual bool
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs);

/// Ensures that the table of all visible declarations inside this
/// context is up to date.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;

void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;

bool
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs) override;

/// Ensures that the table of all visible declarations inside this
/// context is up to date.
void completeVisibleDeclsMap(const DeclContext *DC) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,8 @@ enum ASTRecordTypes {
/// Record code for an unterminated \#pragma clang assume_nonnull begin
/// recorded in a preamble.
PP_ASSUME_NONNULL_LOC = 67,

CXX_ADDED_TEMPLATE_SPECIALIZATION = 68,
};

/// Record types used within a source manager block.
Expand Down Expand Up @@ -1520,6 +1522,9 @@ enum DeclCode {
/// A HLSLBufferDecl record.
DECL_HLSL_BUFFER,

// A decls specilization record.
DECL_SPECIALIZATIONS,

/// An ImplicitConceptSpecializationDecl record.
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,9 @@ class ASTIdentifierLookupTrait;
/// The on-disk hash table(s) used for DeclContext name lookup.
struct DeclContextLookupTable;

/// The on-disk hash table(s) used for specialization decls.
struct LazySpecializationInfoLookupTable;

} // namespace reader

} // namespace serialization
Expand Down Expand Up @@ -596,21 +599,30 @@ class ASTReader
llvm::DenseMap<const DeclContext *,
serialization::reader::DeclContextLookupTable> Lookups;

/// Map from decls to specialized decls.
llvm::DenseMap<const Decl *,
serialization::reader::LazySpecializationInfoLookupTable>
SpecializationsLookups;

// Updates for visible decls can occur for other contexts than just the
// TU, and when we read those update records, the actual context may not
// be available yet, so have this pending map using the ID as a key. It
// will be realized when the context is actually loaded.
struct PendingVisibleUpdate {
// will be realized when the data is actually loaded.
struct UpdateData {
ModuleFile *Mod;
const unsigned char *Data;
};
using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>;
using DeclContextVisibleUpdates = SmallVector<UpdateData, 1>;

/// Updates to the visible declarations of declaration contexts that
/// haven't been loaded yet.
llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates>
PendingVisibleUpdates;

using SpecializationsUpdate = SmallVector<UpdateData, 1>;
llvm::DenseMap<serialization::DeclID, SpecializationsUpdate>
PendingSpecializationsUpdates;

/// The set of C++ or Objective-C classes that have forward
/// declarations that have not yet been linked to their definitions.
llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
Expand All @@ -637,6 +649,11 @@ class ASTReader
llvm::BitstreamCursor &Cursor,
uint64_t Offset, serialization::DeclID ID);

bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
uint64_t Offset, Decl *D);
void AddSpecializations(const Decl *D, const unsigned char *Data,
ModuleFile &M);

/// A vector containing identifiers that have already been
/// loaded.
///
Expand Down Expand Up @@ -1327,6 +1344,11 @@ class ASTReader
const serialization::reader::DeclContextLookupTable *
getLoadedLookupTables(DeclContext *Primary) const;

/// Get the loaded specializations lookup tables for \p D,
/// if any.
serialization::reader::LazySpecializationInfoLookupTable *
getLoadedSpecializationsLookupTables(const Decl *D);

private:
struct ImportedModule {
ModuleFile *Mod;
Expand Down Expand Up @@ -1963,6 +1985,12 @@ class ASTReader
unsigned BlockID,
uint64_t *StartOfBlockOffset = nullptr);

void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;

bool
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs) override;

/// Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
/// lookup table as unmaterialized references.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,10 @@ class ASTWriter : public ASTDeserializationListener,
/// record containing modifications to them.
DeclUpdateMap DeclUpdates;

using SpecializationUpdateMap =
llvm::MapVector<const NamedDecl *, SmallVector<const Decl *>>;
SpecializationUpdateMap SpecializationsUpdates;

using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;

/// Map of first declarations from a chained PCH that point to the
Expand Down Expand Up @@ -517,6 +521,13 @@ class ASTWriter : public ASTDeserializationListener,
bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC);

void GenerateSpecializationInfoLookupTable(
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
llvm::SmallVectorImpl<char> &LookupTable);
uint64_t WriteSpecializationInfoLookupTable(
const NamedDecl *D,
llvm::SmallVectorImpl<const Decl *> &Specializations);

void GenerateNameLookupTable(const DeclContext *DC,
llvm::SmallVectorImpl<char> &LookupTable);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
Expand All @@ -528,6 +539,7 @@ class ASTWriter : public ASTDeserializationListener,
void WriteReferencedSelectorsPool(Sema &SemaRef);
void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
bool IsModule);
void WriteSpecializationsUpdates();
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
void WriteFPPragmaOptions(const FPOptionsOverride &Opts);
Expand All @@ -554,6 +566,7 @@ class ASTWriter : public ASTDeserializationListener,
unsigned DeclEnumAbbrev = 0;
unsigned DeclObjCIvarAbbrev = 0;
unsigned DeclCXXMethodAbbrev = 0;
unsigned DeclSpecializationsAbbrev = 0;

unsigned DeclRefExprAbbrev = 0;
unsigned CharacterLiteralAbbrev = 0;
Expand Down
Loading