Skip to content

Commit 01f0eb2

Browse files
committed
Update @_specialize and @transpose serialization
…to serialize module selectors. This commit also changes the serialization format of @_specialize to serialize name information more simply. Instead of using a conditionally-biased argument count and an SPI group count, which could be inconsistent with the number of identifier IDs in the array, we use a kind field and SPI group count and calculate the argument count. This design seems easier to reason about, less likely to become inconsistent, and a little more compact on disk.
1 parent 7d7a499 commit 01f0eb2

File tree

3 files changed

+73
-47
lines changed

3 files changed

+73
-47
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4476,41 +4476,54 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
44764476
GenericSignatureID specializedSigID;
44774477

44784478
ArrayRef<uint64_t> rawPieceIDs;
4479-
uint64_t numArgs;
4479+
uint8_t targetKind;
44804480
uint64_t numSPIGroups;
44814481
DeclID targetFunID;
44824482

44834483
serialization::decls_block::SpecializeDeclAttrLayout::readRecord(
44844484
scratch, exported, specializationKindVal, specializedSigID,
4485-
targetFunID, numArgs, numSPIGroups, rawPieceIDs);
4485+
targetFunID, targetKind, numSPIGroups, rawPieceIDs);
44864486

4487-
assert(rawPieceIDs.size() == numArgs + numSPIGroups ||
4488-
rawPieceIDs.size() == (numArgs - 1 + numSPIGroups));
44894487
specializationKind = specializationKindVal
44904488
? SpecializeAttr::SpecializationKind::Partial
44914489
: SpecializeAttr::SpecializationKind::Full;
4490+
4491+
SmallVector<Identifier, 4> identPieces;
4492+
// if targetKind == 1 or 2, the first piece is a DeclBaseName and
4493+
// getIdentifier() might crash.
4494+
for (auto id : rawPieceIDs.slice(targetKind == 0 ? 0 : 1))
4495+
identPieces.push_back(MF.getIdentifier(id));
4496+
4497+
assert(identPieces.size() >= numSPIGroups
4498+
&& "has enough identPieces for SPI groups");
4499+
auto spis = makeArrayRef(identPieces).take_back(numSPIGroups);
4500+
auto nameIdents = makeArrayRef(identPieces).drop_back(numSPIGroups);
4501+
44924502
// The 'target' parameter.
44934503
DeclNameRef replacedFunctionName;
4494-
if (numArgs) {
4495-
bool numArgumentLabels = (numArgs == 1) ? 0 : numArgs - 2;
4504+
// 0 = no target; 1 = target has simple name; 2 = target has compound
4505+
// name.
4506+
if (targetKind == 0) {
4507+
assert(rawPieceIDs.size() == identPieces.size()
4508+
&& "no base names when no target");
4509+
assert(nameIdents.empty() && "no extra identifiers when no target");
4510+
} else {
4511+
assert(rawPieceIDs.size() == 1 + identPieces.size()
4512+
&& "one base name when there's a target");
44964513
auto baseName = MF.getDeclBaseName(rawPieceIDs[0]);
4497-
SmallVector<Identifier, 4> pieces;
4498-
if (numArgumentLabels) {
4499-
for (auto pieceID : rawPieceIDs.slice(1, numArgumentLabels))
4500-
pieces.push_back(MF.getIdentifier(pieceID));
4501-
}
4502-
replacedFunctionName = (numArgs == 1)
4503-
? DeclNameRef({baseName}) // simple name
4504-
: DeclNameRef({ctx, baseName, pieces});
4505-
}
45064514

4507-
SmallVector<Identifier, 4> spis;
4508-
if (numSPIGroups) {
4509-
auto numTargetFunctionPiecesToSkip =
4510-
(rawPieceIDs.size() == numArgs + numSPIGroups) ? numArgs
4511-
: numArgs - 1;
4512-
for (auto id : rawPieceIDs.slice(numTargetFunctionPiecesToSkip))
4513-
spis.push_back(MF.getIdentifier(id));
4515+
assert(!nameIdents.empty() && "has module selector for target");
4516+
auto modSelector = nameIdents[0];
4517+
auto argLabels = nameIdents.drop_front(1);
4518+
4519+
if (targetKind == 1) {
4520+
assert(argLabels.empty() && "no arg labels with simple DeclName");
4521+
replacedFunctionName = DeclNameRef(ctx, modSelector, baseName);
4522+
} else {
4523+
assert(targetKind == 2 && "targetKind is a known value");
4524+
replacedFunctionName = DeclNameRef(ctx, modSelector, baseName,
4525+
argLabels);
4526+
}
45144527
}
45154528

45164529
auto specializedSig = MF.getGenericSignature(specializedSigID);
@@ -4681,19 +4694,21 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
46814694

46824695
case decls_block::Transpose_DECL_ATTR: {
46834696
bool isImplicit;
4697+
uint64_t origModSelId;
46844698
uint64_t origNameId;
46854699
DeclID origDeclId;
4686-
ArrayRef<uint64_t> parameters;
4700+
ArrayRef<uint64_t> params;
46874701

46884702
serialization::decls_block::TransposeDeclAttrLayout::readRecord(
4689-
scratch, isImplicit, origNameId, origDeclId, parameters);
4703+
scratch, isImplicit, origModSelId, origNameId, origDeclId, params);
46904704

4691-
DeclNameRefWithLoc origName{
4692-
DeclNameRef(MF.getDeclBaseName(origNameId)), DeclNameLoc(), None};
4705+
DeclNameRef origNameRef(ctx, MF.getIdentifier(origModSelId),
4706+
MF.getDeclBaseName(origNameId));
4707+
DeclNameRefWithLoc origName{origNameRef, DeclNameLoc(), None};
46934708
auto *origDecl = cast<AbstractFunctionDecl>(MF.getDecl(origDeclId));
4694-
llvm::SmallBitVector parametersBitVector(parameters.size());
4695-
for (unsigned i : indices(parameters))
4696-
parametersBitVector[i] = parameters[i];
4709+
llvm::SmallBitVector parametersBitVector(params.size());
4710+
for (unsigned i : indices(params))
4711+
parametersBitVector[i] = params[i];
46974712
auto *indices = IndexSubset::get(ctx, parametersBitVector);
46984713
auto *transposeAttr =
46994714
TransposeAttr::create(ctx, isImplicit, SourceLoc(), SourceRange(),

lib/Serialization/ModuleFormat.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 624; // DeclNameRef ModuleSelector fields
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 625; // New @_specialize layout
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///
@@ -1915,9 +1915,9 @@ namespace decls_block {
19151915
BCFixed<1>, // specialization kind
19161916
GenericSignatureIDField, // specialized signature
19171917
DeclIDField, // target function
1918-
BCVBR<4>, // # of arguments (+1) or 1 if simple decl name, 0 if no target
1918+
BCFixed<2>, // 0 = no target func name, 1 = simple name, 2 = compound name
19191919
BCVBR<4>, // # of SPI groups
1920-
BCArray<IdentifierIDField> // target function pieces, spi groups
1920+
BCArray<IdentifierIDField> // target func base name/mod sel/args, spi groups
19211921
>;
19221922

19231923
using DifferentiableDeclAttrLayout = BCRecordLayout<
@@ -1943,6 +1943,7 @@ namespace decls_block {
19431943
using TransposeDeclAttrLayout = BCRecordLayout<
19441944
Transpose_DECL_ATTR,
19451945
BCFixed<1>, // Implicit flag.
1946+
IdentifierIDField, // Original module selector.
19461947
IdentifierIDField, // Original name.
19471948
DeclIDField, // Original function declaration.
19481949
BCArray<BCFixed<1>> // Transposed parameter indices' bitvector.

lib/Serialization/Serialization.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2528,33 +2528,40 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
25282528

25292529
SmallVector<IdentifierID, 4> pieces;
25302530

2531-
// encodes whether this a a simple or compound name by adding one.
2532-
size_t numArgs = 0;
2533-
if (targetFun) {
2531+
// 0 = no target; 1 = target has simple name; 2 = target has compound
2532+
// name. 3 is a dummy value.
2533+
uint8_t targetKind = 3;
2534+
if (!targetFun) {
2535+
targetKind = 0;
2536+
} else {
25342537
pieces.push_back(S.addDeclBaseNameRef(targetFun.getBaseName()));
2535-
for (auto argName : targetFun.getArgumentNames())
2536-
pieces.push_back(S.addDeclBaseNameRef(argName));
2538+
pieces.push_back(S.addDeclBaseNameRef(targetFun.getModuleSelector()));
2539+
25372540
if (targetFun.isSimpleName()) {
2538-
assert(pieces.size() == 1);
2539-
numArgs = 1;
2540-
} else
2541-
numArgs = pieces.size() + 1;
2541+
targetKind = 1;
2542+
} else {
2543+
targetKind = 2;
2544+
for (auto argName : targetFun.getArgumentNames())
2545+
pieces.push_back(S.addDeclBaseNameRef(argName));
2546+
}
25422547
}
2548+
assert(targetKind != 3 && "didn't initialize targetKind?");
25432549

2550+
auto numSPIGroups = attr->getSPIGroups().size();
25442551
for (auto spi : attr->getSPIGroups()) {
25452552
assert(!spi.empty() && "Empty SPI name");
25462553
pieces.push_back(S.addDeclBaseNameRef(spi));
25472554
}
25482555

2549-
auto numSPIGroups = attr->getSPIGroups().size();
2550-
assert(pieces.size() == numArgs + numSPIGroups ||
2551-
pieces.size() == (numArgs - 1 + numSPIGroups));
2556+
assert(targetKind != 0 || pieces.size() == numSPIGroups);
2557+
assert(targetKind == 0 || pieces.size() ==
2558+
2 + targetFun.getArgumentNames().size() + numSPIGroups);
25522559

25532560
SpecializeDeclAttrLayout::emitRecord(
25542561
S.Out, S.ScratchRecord, abbrCode, (unsigned)attr->isExported(),
25552562
(unsigned)attr->getSpecializationKind(),
25562563
S.addGenericSignatureRef(attr->getSpecializedSignature()),
2557-
S.addDeclRef(targetFunDecl), numArgs, numSPIGroups, pieces);
2564+
S.addDeclRef(targetFunDecl), targetKind, numSPIGroups, pieces);
25582565
return;
25592566
}
25602567

@@ -2665,6 +2672,9 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
26652672
assert(attr->getOriginalFunction() &&
26662673
"`@transpose` attribute should have original declaration set "
26672674
"during construction or parsing");
2675+
auto origModSel = attr->getOriginalFunctionName().Name
2676+
.getModuleSelector();
2677+
IdentifierID origModSelId = S.addDeclBaseNameRef(origModSel);
26682678
auto origName = attr->getOriginalFunctionName().Name.getBaseName();
26692679
IdentifierID origNameId = S.addDeclBaseNameRef(origName);
26702680
DeclID origDeclID = S.addDeclRef(attr->getOriginalFunction());
@@ -2674,8 +2684,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
26742684
for (unsigned i : range(parameterIndices->getCapacity()))
26752685
paramIndicesVector.push_back(parameterIndices->contains(i));
26762686
TransposeDeclAttrLayout::emitRecord(
2677-
S.Out, S.ScratchRecord, abbrCode, attr->isImplicit(), origNameId,
2678-
origDeclID, paramIndicesVector);
2687+
S.Out, S.ScratchRecord, abbrCode, attr->isImplicit(), origModSelId,
2688+
origNameId, origDeclID, paramIndicesVector);
26792689
return;
26802690
}
26812691
}

0 commit comments

Comments
 (0)