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;
|
ValueID ValID, ValID2;
|
||||||
TypeID TyID, TyID2;
|
TypeID TyID, TyID2;
|
||||||
TypeID ConcreteTyID;
|
TypeID ConcreteTyID;
|
||||||
|
DeclID ProtoID;
|
||||||
|
ModuleID OwningModuleID;
|
||||||
SourceLoc SLoc;
|
SourceLoc SLoc;
|
||||||
ArrayRef<uint64_t> ListOfValues;
|
ArrayRef<uint64_t> ListOfValues;
|
||||||
SILLocation Loc = SILFileLocation(SLoc);
|
SILLocation Loc = SILFileLocation(SLoc);
|
||||||
@@ -673,6 +675,14 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
|||||||
case SIL_INST_NO_OPERAND:
|
case SIL_INST_NO_OPERAND:
|
||||||
SILInstNoOperandLayout::readRecord(scratch, OpCode);
|
SILInstNoOperandLayout::readRecord(scratch, OpCode);
|
||||||
break;
|
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;
|
ValueBase *ResultVal;
|
||||||
@@ -1362,7 +1372,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
|||||||
ResultTy);
|
ResultTy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ValueKind::WitnessMethodInst:
|
|
||||||
case ValueKind::ProtocolMethodInst:
|
case ValueKind::ProtocolMethodInst:
|
||||||
case ValueKind::ClassMethodInst:
|
case ValueKind::ClassMethodInst:
|
||||||
case ValueKind::SuperMethodInst:
|
case ValueKind::SuperMethodInst:
|
||||||
@@ -1370,8 +1379,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
|||||||
// Format: a type, an operand and a SILDeclRef. Use SILOneTypeValuesLayout:
|
// Format: a type, an operand and a SILDeclRef. Use SILOneTypeValuesLayout:
|
||||||
// type, Attr, SILDeclRef (DeclID, Kind, uncurryLevel, IsObjC),
|
// type, Attr, SILDeclRef (DeclID, Kind, uncurryLevel, IsObjC),
|
||||||
// and an operand.
|
// and an operand.
|
||||||
// WitnessMethodInst is additionally optionally followed by a
|
|
||||||
// ProtocolConformance record.
|
|
||||||
unsigned NextValueIndex = 1;
|
unsigned NextValueIndex = 1;
|
||||||
SILDeclRef DRef = getSILDeclRef(MF, ListOfValues, NextValueIndex);
|
SILDeclRef DRef = getSILDeclRef(MF, ListOfValues, NextValueIndex);
|
||||||
SILType Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory);
|
SILType Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory);
|
||||||
@@ -1384,14 +1391,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
|||||||
|
|
||||||
switch ((ValueKind)OpCode) {
|
switch ((ValueKind)OpCode) {
|
||||||
default: assert(0 && "Out of sync with parent switch");
|
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:
|
case ValueKind::ProtocolMethodInst:
|
||||||
ResultVal = Builder.createProtocolMethod(Loc,
|
ResultVal = Builder.createProtocolMethod(Loc,
|
||||||
getLocalValue(ListOfValues[NextValueIndex],
|
getLocalValue(ListOfValues[NextValueIndex],
|
||||||
@@ -1419,6 +1418,24 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
|||||||
}
|
}
|
||||||
break;
|
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: {
|
case ValueKind::DynamicMethodBranchInst: {
|
||||||
// Format: a typed value, a SILDeclRef, a BasicBlock ID for method,
|
// Format: a typed value, a SILDeclRef, a BasicBlock ID for method,
|
||||||
// a BasicBlock ID for no method. Use SILOneTypeValuesLayout.
|
// a BasicBlock ID for no method. Use SILOneTypeValuesLayout.
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ namespace sil_block {
|
|||||||
SIL_WITNESS_ASSOC_PROTOCOL,
|
SIL_WITNESS_ASSOC_PROTOCOL,
|
||||||
SIL_WITNESS_ASSOC_ENTRY,
|
SIL_WITNESS_ASSOC_ENTRY,
|
||||||
SIL_GENERIC_OUTER_PARAMS,
|
SIL_GENERIC_OUTER_PARAMS,
|
||||||
|
SIL_INST_WITNESS_METHOD,
|
||||||
|
|
||||||
// We also share these layouts from the decls block. Their enumerators must
|
// We also share these layouts from the decls block. Their enumerators must
|
||||||
// not overlap with ours.
|
// not overlap with ours.
|
||||||
@@ -346,6 +347,20 @@ namespace sil_block {
|
|||||||
SIL_GENERIC_OUTER_PARAMS,
|
SIL_GENERIC_OUTER_PARAMS,
|
||||||
DeclIDField // The decl id of the outer param if any.
|
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
|
} // 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_PROTOCOL);
|
||||||
BLOCK_RECORD(sil_block, SIL_WITNESS_ASSOC_ENTRY);
|
BLOCK_RECORD(sil_block, SIL_WITNESS_ASSOC_ENTRY);
|
||||||
BLOCK_RECORD(sil_block, SIL_GENERIC_OUTER_PARAMS);
|
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.
|
// These layouts can exist in both decl blocks and sil blocks.
|
||||||
#define BLOCK_RECORD_WITH_NAMESPACE(K, X) emitRecordID(Out, X, #X, nameBuffer)
|
#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) {
|
for (auto conformance : conformancesToWrite) {
|
||||||
S.writeConformance(conformance->getProtocol(), conformance, nullptr,
|
S.writeConformance(conformance->getProtocol(), conformance, nullptr,
|
||||||
SILAbbrCodes, /*writeIncomplete=*/true);
|
SILAbbrCodes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1123,23 +1123,38 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
|
|||||||
SILType Ty = AMI->getLookupType();
|
SILType Ty = AMI->getLookupType();
|
||||||
SILType Ty2 = AMI->getType(0);
|
SILType Ty2 = AMI->getType(0);
|
||||||
|
|
||||||
SmallVector<ValueID, 7> ListOfValues;
|
SmallVector<ValueID, 8> ListOfValues;
|
||||||
ListOfValues.push_back(AMI->isVolatile());
|
|
||||||
handleSILDeclRef(S, AMI->getMember(), ListOfValues);
|
handleSILDeclRef(S, AMI->getMember(), ListOfValues);
|
||||||
ListOfValues.push_back(S.addTypeRef(Ty2.getSwiftRValueType()));
|
|
||||||
ListOfValues.push_back((unsigned)Ty2.getCategory());
|
|
||||||
|
|
||||||
SILOneTypeValuesLayout::emitRecord(Out, ScratchRecord,
|
DeclID ConformanceProto;
|
||||||
SILAbbrCodes[SILOneTypeValuesLayout::Code], (unsigned)SI.getKind(),
|
TypeID AdopterTy;
|
||||||
S.addTypeRef(Ty.getSwiftRValueType()),
|
ModuleID ConformanceModule;
|
||||||
(unsigned)Ty.getCategory(), ListOfValues);
|
bool WriteConformance = false;
|
||||||
|
|
||||||
if (AMI->getConformance())
|
if (auto *Conformance = AMI->getConformance()) {
|
||||||
S.writeConformance(
|
ConformanceProto = S.addDeclRef(Conformance->getProtocol());
|
||||||
cast<ProtocolDecl>(AMI->getMember().getDecl()->getDeclContext()),
|
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(),
|
AMI->getConformance(),
|
||||||
nullptr,
|
nullptr,
|
||||||
SILAbbrCodes);
|
SILAbbrCodes);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1525,6 +1540,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
|
|||||||
registerSILAbbr<SILGenericOuterParamsLayout>();
|
registerSILAbbr<SILGenericOuterParamsLayout>();
|
||||||
|
|
||||||
registerSILAbbr<SILInstCastLayout>();
|
registerSILAbbr<SILInstCastLayout>();
|
||||||
|
registerSILAbbr<SILInstWitnessMethodLayout>();
|
||||||
|
|
||||||
// Register the abbreviation codes so these layouts can exist in both
|
// Register the abbreviation codes so these layouts can exist in both
|
||||||
// decl blocks and sil blocks.
|
// decl blocks and sil blocks.
|
||||||
|
|||||||
Reference in New Issue
Block a user