Skip to content

[Serialization] Collapse indirection in DeclContextID #26813

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

Merged
merged 2 commits into from
Aug 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/swift/Serialization/DeclTypeRecordNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ PATTERN(VAR)
OTHER(PARAMETERLIST, 210)
// 211 is unused
OTHER(FOREIGN_ERROR_CONVENTION, 212)
OTHER(DECL_CONTEXT, 213)
// 213 is unused
OTHER(XREF_TYPE_PATH_PIECE, 214)
OTHER(XREF_VALUE_PATH_PIECE, 215)
OTHER(XREF_EXTENSION_PATH_PIECE, 216)
Expand Down
5 changes: 1 addition & 4 deletions include/swift/Serialization/ModuleFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,6 @@ class ModuleFile
/// Decls referenced by this module.
MutableArrayRef<Serialized<Decl*>> Decls;

/// DeclContexts referenced by this module.
MutableArrayRef<Serialized<DeclContext*>> DeclContexts;

/// Local DeclContexts referenced by this module.
MutableArrayRef<Serialized<DeclContext*>> LocalDeclContexts;

Expand Down Expand Up @@ -862,7 +859,7 @@ class ModuleFile
DeclContext *getDeclContext(serialization::DeclContextID DID);

/// Returns the local decl context with the given ID, deserializing it if needed.
DeclContext *getLocalDeclContext(serialization::DeclContextID DID);
DeclContext *getLocalDeclContext(serialization::LocalDeclContextID DID);

/// Returns the appropriate module for the given ID.
ModuleDecl *getModule(serialization::ModuleID MID);
Expand Down
70 changes: 54 additions & 16 deletions include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t SWIFTMODULE_VERSION_MINOR = 514; // specialize attr
const uint16_t SWIFTMODULE_VERSION_MINOR = 515; // remove DeclContext indirection

using DeclIDField = BCFixed<31>;

Expand All @@ -66,9 +66,58 @@ using TypeIDWithBitField = BCFixed<32>;
using IdentifierID = DeclID;
using IdentifierIDField = DeclIDField;

// DeclContextID must be the same as DeclID because it is stored in the same way.
using DeclContextID = DeclID;
using DeclContextIDField = DeclIDField;
// LocalDeclContextID must be the same as DeclID because it is stored in the
// same way.
using LocalDeclContextID = DeclID;
using LocalDeclContextIDField = DeclIDField;

/// Stores either a DeclID or a LocalDeclContextID, using 32 bits.
class DeclContextID {
int32_t rawValue;
explicit DeclContextID(int32_t rawValue) : rawValue(rawValue) {}
public:
DeclContextID() : DeclContextID(0) {}

static DeclContextID forDecl(DeclID value) {
assert(value && "should encode null using DeclContextID()");
assert(llvm::isUInt<31>(value) && "too many DeclIDs");
return DeclContextID(static_cast<int32_t>(value));
}
static DeclContextID forLocalDeclContext(LocalDeclContextID value) {
assert(value && "should encode null using DeclContextID()");
assert(llvm::isUInt<31>(value) && "too many LocalDeclContextIDs");
return DeclContextID(-static_cast<int32_t>(value));
}

explicit operator bool() const {
return rawValue != 0;
}

Optional<DeclID> getAsDeclID() const {
if (rawValue > 0)
return DeclID(rawValue);
return None;
}

Optional<LocalDeclContextID> getAsLocalDeclContextID() const {
if (rawValue < 0)
return LocalDeclContextID(-rawValue);
return None;
}

static DeclContextID getFromOpaqueValue(uint32_t opaqueValue) {
return DeclContextID(opaqueValue);
}
uint32_t getOpaqueValue() const { return rawValue; }
};

class DeclContextIDField : public BCFixed<32> {
public:
static DeclContextID convert(uint64_t rawValue) {
assert(llvm::isUInt<32>(rawValue));
return DeclContextID::getFromOpaqueValue(rawValue);
}
};

// NormalConformanceID must be the same as DeclID because it is stored
// in the same way.
Expand Down Expand Up @@ -1154,7 +1203,7 @@ namespace decls_block {
StaticSpellingKindField, // spelling of 'static' or 'class'
BCVBR<3>, // numpatterns
BCArray<DeclContextIDField> // init contexts
// The patterns and decl-contexts trail the record.
// The patterns trail the record.
>;

template <unsigned Code>
Expand Down Expand Up @@ -1520,16 +1569,6 @@ namespace decls_block {
BCFixed<2> // modref value
>;

using DeclContextLayout = BCRecordLayout<
DECL_CONTEXT,
// If this DeclContext is a local context, this is an
// index into the local decl context table.
// If this DeclContext is a Decl (and not a DeclContext
// *at all*, this is an index into the decl table.
DeclContextIDField,
BCFixed<1> // is a decl
>;

using ForeignErrorConventionLayout = BCRecordLayout<
FOREIGN_ERROR_CONVENTION,
ForeignErrorConventionKindField, // kind
Expand Down Expand Up @@ -1739,7 +1778,6 @@ namespace index_block {

ENTRY_POINT,
LOCAL_DECL_CONTEXT_OFFSETS,
DECL_CONTEXT_OFFSETS,
LOCAL_TYPE_DECLS,
OPAQUE_RETURN_TYPE_DECLS,
GENERIC_ENVIRONMENT_OFFSETS,
Expand Down
66 changes: 18 additions & 48 deletions lib/Serialization/Deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1805,7 +1805,7 @@ StringRef ModuleFile::getIdentifierText(IdentifierID IID) {
return rawStrPtr.slice(0, terminatorOffset);
}

DeclContext *ModuleFile::getLocalDeclContext(DeclContextID DCID) {
DeclContext *ModuleFile::getLocalDeclContext(LocalDeclContextID DCID) {
assert(DCID != 0 && "invalid local DeclContext ID 0");
auto &declContextOrOffset = LocalDeclContexts[DCID-1];

Expand Down Expand Up @@ -1893,56 +1893,24 @@ DeclContext *ModuleFile::getLocalDeclContext(DeclContextID DCID) {
}

DeclContext *ModuleFile::getDeclContext(DeclContextID DCID) {
if (DCID == 0)
if (!DCID)
return FileContext;

assert(DCID <= DeclContexts.size() && "invalid DeclContext ID");
auto &declContextOrOffset = DeclContexts[DCID-1];
if (Optional<LocalDeclContextID> contextID = DCID.getAsLocalDeclContextID())
return getLocalDeclContext(contextID.getValue());

if (declContextOrOffset.isComplete())
return declContextOrOffset;

BCOffsetRAII restoreOffset(DeclTypeCursor);
DeclTypeCursor.JumpToBit(declContextOrOffset);
auto entry = DeclTypeCursor.advance();
auto D = getDecl(DCID.getAsDeclID().getValue());

if (entry.Kind != llvm::BitstreamEntry::Record)
fatal();

SmallVector<uint64_t, 64> scratch;
StringRef blobData;
if (auto GTD = dyn_cast<GenericTypeDecl>(D))
return GTD;
if (auto ED = dyn_cast<ExtensionDecl>(D))
return ED;
if (auto AFD = dyn_cast<AbstractFunctionDecl>(D))
return AFD;
if (auto SD = dyn_cast<SubscriptDecl>(D))
return SD;

unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch, &blobData);

if (recordID != decls_block::DECL_CONTEXT)
llvm_unreachable("Expected a DECL_CONTEXT record");

DeclContextID declOrDeclContextId;
bool isDecl;

decls_block::DeclContextLayout::readRecord(scratch, declOrDeclContextId,
isDecl);

if (!isDecl)
return getLocalDeclContext(declOrDeclContextId);

auto D = getDecl(declOrDeclContextId);

if (auto ND = dyn_cast<NominalTypeDecl>(D)) {
declContextOrOffset = ND;
} else if (auto ED = dyn_cast<ExtensionDecl>(D)) {
declContextOrOffset = ED;
} else if (auto AFD = dyn_cast<AbstractFunctionDecl>(D)) {
declContextOrOffset = AFD;
} else if (auto SD = dyn_cast<SubscriptDecl>(D)) {
declContextOrOffset = SD;
} else if (auto TAD = dyn_cast<TypeAliasDecl>(D)) {
declContextOrOffset = TAD;
} else {
llvm_unreachable("Unknown Decl : DeclContext kind");
}

return declContextOrOffset;
llvm_unreachable("Unknown Decl : DeclContext kind");
}

ModuleDecl *ModuleFile::getModule(ModuleID MID) {
Expand Down Expand Up @@ -3195,8 +3163,10 @@ class swift::DeclDeserializer {
}

patterns.emplace_back(pattern.get(), DeclContextID());
if (!initContextIDs.empty())
patterns.back().second = initContextIDs[i];
if (!initContextIDs.empty()) {
patterns.back().second =
DeclContextID::getFromOpaqueValue(initContextIDs[i]);
}
}

auto binding =
Expand Down
4 changes: 0 additions & 4 deletions lib/Serialization/ModuleFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,10 +874,6 @@ bool ModuleFile::readIndexBlock(llvm::BitstreamCursor &cursor) {
assert(blobData.empty());
allocateBuffer(Decls, scratch);
break;
case index_block::DECL_CONTEXT_OFFSETS:
assert(blobData.empty());
allocateBuffer(DeclContexts, scratch);
break;
case index_block::TYPE_OFFSETS:
assert(blobData.empty());
allocateBuffer(Types, scratch);
Expand Down
Loading