mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Serialization] witness_method should reference existing conformances.
Part of a series of commits to remove redundantly-serialized conformances. Swift SVN r22196
This commit is contained in:
@@ -614,6 +614,8 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||
ValueID ValID, ValID2;
|
||||
TypeID TyID, TyID2;
|
||||
TypeID ConcreteTyID;
|
||||
DeclID ProtoID;
|
||||
ModuleID OwningModuleID;
|
||||
SourceLoc SLoc;
|
||||
ArrayRef<uint64_t> ListOfValues;
|
||||
SILLocation Loc = SILFileLocation(SLoc);
|
||||
@@ -673,6 +675,14 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||
case SIL_INST_NO_OPERAND:
|
||||
SILInstNoOperandLayout::readRecord(scratch, OpCode);
|
||||
break;
|
||||
case SIL_INST_WITNESS_METHOD:
|
||||
SILInstWitnessMethodLayout::readRecord(scratch, TyID, TyCategory, Attr,
|
||||
TyID2, TyCategory2,
|
||||
ProtoID, ConcreteTyID,
|
||||
OwningModuleID,
|
||||
ListOfValues);
|
||||
OpCode = (unsigned)ValueKind::WitnessMethodInst;
|
||||
break;
|
||||
}
|
||||
|
||||
ValueBase *ResultVal;
|
||||
@@ -1362,7 +1372,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||
ResultTy);
|
||||
break;
|
||||
}
|
||||
case ValueKind::WitnessMethodInst:
|
||||
case ValueKind::ProtocolMethodInst:
|
||||
case ValueKind::ClassMethodInst:
|
||||
case ValueKind::SuperMethodInst:
|
||||
@@ -1370,8 +1379,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||
// Format: a type, an operand and a SILDeclRef. Use SILOneTypeValuesLayout:
|
||||
// type, Attr, SILDeclRef (DeclID, Kind, uncurryLevel, IsObjC),
|
||||
// and an operand.
|
||||
// WitnessMethodInst is additionally optionally followed by a
|
||||
// ProtocolConformance record.
|
||||
unsigned NextValueIndex = 1;
|
||||
SILDeclRef DRef = getSILDeclRef(MF, ListOfValues, NextValueIndex);
|
||||
SILType Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory);
|
||||
@@ -1384,14 +1391,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||
|
||||
switch ((ValueKind)OpCode) {
|
||||
default: assert(0 && "Out of sync with parent switch");
|
||||
case ValueKind::WitnessMethodInst: {
|
||||
auto conformance = MF->maybeReadConformance(Ty.getSwiftRValueType(),
|
||||
SILCursor);
|
||||
ResultVal = Builder.createWitnessMethod(Loc, Ty,
|
||||
conformance.getValueOr(nullptr),
|
||||
DRef, operandTy, IsVolatile);
|
||||
break;
|
||||
}
|
||||
case ValueKind::ProtocolMethodInst:
|
||||
ResultVal = Builder.createProtocolMethod(Loc,
|
||||
getLocalValue(ListOfValues[NextValueIndex],
|
||||
@@ -1419,6 +1418,24 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ValueKind::WitnessMethodInst: {
|
||||
unsigned NextValueIndex = 0;
|
||||
SILDeclRef DRef = getSILDeclRef(MF, ListOfValues, NextValueIndex);
|
||||
assert(ListOfValues.size() >= NextValueIndex &&
|
||||
"Out of entries for MethodInst");
|
||||
|
||||
SILType Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory);
|
||||
SILType OperandTy = getSILType(MF->getType(TyID2),
|
||||
(SILValueCategory)TyCategory2);
|
||||
|
||||
auto *Proto = cast_or_null<ProtocolDecl>(MF->getDecl(ProtoID));
|
||||
auto *Conformance = MF->readReferencedConformance(Proto, ConcreteTyID,
|
||||
OwningModuleID,
|
||||
SILCursor);
|
||||
ResultVal = Builder.createWitnessMethod(Loc, Ty, Conformance, DRef,
|
||||
OperandTy, Attr);
|
||||
break;
|
||||
}
|
||||
case ValueKind::DynamicMethodBranchInst: {
|
||||
// Format: a typed value, a SILDeclRef, a BasicBlock ID for method,
|
||||
// a BasicBlock ID for no method. Use SILOneTypeValuesLayout.
|
||||
|
||||
@@ -136,6 +136,7 @@ namespace sil_block {
|
||||
SIL_WITNESS_ASSOC_PROTOCOL,
|
||||
SIL_WITNESS_ASSOC_ENTRY,
|
||||
SIL_GENERIC_OUTER_PARAMS,
|
||||
SIL_INST_WITNESS_METHOD,
|
||||
|
||||
// We also share these layouts from the decls block. Their enumerators must
|
||||
// not overlap with ours.
|
||||
@@ -346,6 +347,20 @@ namespace sil_block {
|
||||
SIL_GENERIC_OUTER_PARAMS,
|
||||
DeclIDField // The decl id of the outer param if any.
|
||||
>;
|
||||
|
||||
using SILInstWitnessMethodLayout = BCRecordLayout<
|
||||
SIL_INST_WITNESS_METHOD,
|
||||
TypeIDField, // result type
|
||||
SILTypeCategoryField,
|
||||
BCFixed<1>, // volatile?
|
||||
TypeIDField, // lookup type
|
||||
SILTypeCategoryField,
|
||||
DeclIDField, // conformance proto
|
||||
TypeIDField, // conformance type
|
||||
ModuleIDField, // conformance module
|
||||
BCArray<ValueIDField> // SILDeclRef
|
||||
// may be trailed by an inline protocol conformance
|
||||
>;
|
||||
}
|
||||
|
||||
} // end namespace serialization
|
||||
|
||||
@@ -293,6 +293,7 @@ void Serializer::writeBlockInfoBlock() {
|
||||
BLOCK_RECORD(sil_block, SIL_WITNESS_ASSOC_PROTOCOL);
|
||||
BLOCK_RECORD(sil_block, SIL_WITNESS_ASSOC_ENTRY);
|
||||
BLOCK_RECORD(sil_block, SIL_GENERIC_OUTER_PARAMS);
|
||||
BLOCK_RECORD(sil_block, SIL_INST_WITNESS_METHOD);
|
||||
|
||||
// These layouts can exist in both decl blocks and sil blocks.
|
||||
#define BLOCK_RECORD_WITH_NAMESPACE(K, X) emitRecordID(Out, X, #X, nameBuffer)
|
||||
|
||||
@@ -382,7 +382,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
|
||||
|
||||
for (auto conformance : conformancesToWrite) {
|
||||
S.writeConformance(conformance->getProtocol(), conformance, nullptr,
|
||||
SILAbbrCodes, /*writeIncomplete=*/true);
|
||||
SILAbbrCodes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1123,23 +1123,38 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
|
||||
SILType Ty = AMI->getLookupType();
|
||||
SILType Ty2 = AMI->getType(0);
|
||||
|
||||
SmallVector<ValueID, 7> ListOfValues;
|
||||
ListOfValues.push_back(AMI->isVolatile());
|
||||
SmallVector<ValueID, 8> ListOfValues;
|
||||
handleSILDeclRef(S, AMI->getMember(), ListOfValues);
|
||||
ListOfValues.push_back(S.addTypeRef(Ty2.getSwiftRValueType()));
|
||||
ListOfValues.push_back((unsigned)Ty2.getCategory());
|
||||
|
||||
SILOneTypeValuesLayout::emitRecord(Out, ScratchRecord,
|
||||
SILAbbrCodes[SILOneTypeValuesLayout::Code], (unsigned)SI.getKind(),
|
||||
S.addTypeRef(Ty.getSwiftRValueType()),
|
||||
(unsigned)Ty.getCategory(), ListOfValues);
|
||||
DeclID ConformanceProto;
|
||||
TypeID AdopterTy;
|
||||
ModuleID ConformanceModule;
|
||||
bool WriteConformance = false;
|
||||
|
||||
if (AMI->getConformance())
|
||||
S.writeConformance(
|
||||
cast<ProtocolDecl>(AMI->getMember().getDecl()->getDeclContext()),
|
||||
if (auto *Conformance = AMI->getConformance()) {
|
||||
ConformanceProto = S.addDeclRef(Conformance->getProtocol());
|
||||
WriteConformance = S.encodeReferencedConformance(Conformance,
|
||||
AdopterTy,
|
||||
ConformanceModule,
|
||||
true);
|
||||
} else {
|
||||
ConformanceProto = S.addDeclRef(nullptr);
|
||||
}
|
||||
|
||||
SILInstWitnessMethodLayout::emitRecord(Out, ScratchRecord,
|
||||
SILAbbrCodes[SILInstWitnessMethodLayout::Code],
|
||||
S.addTypeRef(Ty.getSwiftRValueType()), (unsigned)Ty.getCategory(),
|
||||
AMI->isVolatile(),
|
||||
S.addTypeRef(Ty2.getSwiftRValueType()), (unsigned)Ty2.getCategory(),
|
||||
ConformanceProto, AdopterTy, ConformanceModule,
|
||||
ListOfValues);
|
||||
|
||||
if (WriteConformance) {
|
||||
S.writeConformance(AMI->getConformance()->getProtocol(),
|
||||
AMI->getConformance(),
|
||||
nullptr,
|
||||
SILAbbrCodes);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1525,6 +1540,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
|
||||
registerSILAbbr<SILGenericOuterParamsLayout>();
|
||||
|
||||
registerSILAbbr<SILInstCastLayout>();
|
||||
registerSILAbbr<SILInstWitnessMethodLayout>();
|
||||
|
||||
// Register the abbreviation codes so these layouts can exist in both
|
||||
// decl blocks and sil blocks.
|
||||
|
||||
Reference in New Issue
Block a user