[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:
Jordan Rose
2014-09-23 02:06:21 +00:00
parent eea6c17456
commit 82011c98ef
4 changed files with 75 additions and 26 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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)

View File

@@ -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.