mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SIL Serialization: perform SIL linking right after SILGen.
Add a SILLinkage mode "Deserialized" to make sure IRGen will emit hidden symbols for deserialized SILFunction. Inside SIL linker, set Linkage to external if we only have a declaration for a callee function. Both sil block and decl block in a module can emit an array of substitutions. To share the serialization between SILSerializer and Serializer, we modify the interface to pass in the abbreviation codes to write functions and to pass in a cursor to read functions. We now correctly handle the serialization of Substitutions in SpecializeInst. For a deserialized SILFunction, we now temporarily set its SILLocation and DebugScope to an empty FileLocation. Once mandatory inliner sets the SILLocation to the location of ApplyInst, a null SILLocation and a null DebugScope may work for a deserialized SILFunction. Update testing cases to reflect that we are now inlining transparent functions from modules, or to disable SILDeserializer for now (I am not sure how to update those testing cases). Swift SVN r8582
This commit is contained in:
@@ -31,6 +31,7 @@ enum class SILLinkage : unsigned char {
|
|||||||
External,
|
External,
|
||||||
Thunk,
|
Thunk,
|
||||||
Internal,
|
Internal,
|
||||||
|
Deserialized // Deserialized from a module.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum IsTransparent_t { IsNotTransparent, IsTransparent };
|
enum IsTransparent_t { IsNotTransparent, IsTransparent };
|
||||||
|
|||||||
@@ -685,6 +685,12 @@ bool LinkEntity::isThunk() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LinkEntity::isDeserialized() const {
|
||||||
|
if (getKind() == Kind::SILFunction)
|
||||||
|
return getSILFunction()->getLinkage() == SILLinkage::Deserialized;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity) {
|
LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity) {
|
||||||
LinkInfo result;
|
LinkInfo result;
|
||||||
|
|
||||||
@@ -704,6 +710,9 @@ LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity) {
|
|||||||
// Clang thunks are linkonce_odr and hidden.
|
// Clang thunks are linkonce_odr and hidden.
|
||||||
result.Linkage = llvm::GlobalValue::LinkOnceODRLinkage;
|
result.Linkage = llvm::GlobalValue::LinkOnceODRLinkage;
|
||||||
result.Visibility = llvm::GlobalValue::HiddenVisibility;
|
result.Visibility = llvm::GlobalValue::HiddenVisibility;
|
||||||
|
} else if (entity.isDeserialized()) {
|
||||||
|
result.Linkage = llvm::GlobalValue::LinkOnceODRLinkage;
|
||||||
|
result.Visibility = llvm::GlobalValue::HiddenVisibility;
|
||||||
} else {
|
} else {
|
||||||
// Give everything else external linkage.
|
// Give everything else external linkage.
|
||||||
result.Linkage = llvm::GlobalValue::ExternalLinkage;
|
result.Linkage = llvm::GlobalValue::ExternalLinkage;
|
||||||
|
|||||||
@@ -397,6 +397,7 @@ public:
|
|||||||
void mangle(SmallVectorImpl<char> &buffer) const;
|
void mangle(SmallVectorImpl<char> &buffer) const;
|
||||||
bool isLocalLinkage() const;
|
bool isLocalLinkage() const;
|
||||||
bool isThunk() const;
|
bool isThunk() const;
|
||||||
|
bool isDeserialized() const;
|
||||||
|
|
||||||
ValueDecl *getDecl() const {
|
ValueDecl *getDecl() const {
|
||||||
assert(isDeclKind(getKind()));
|
assert(isDeclKind(getKind()));
|
||||||
|
|||||||
@@ -493,6 +493,9 @@ static bool parseSILLinkage(SILLinkage &Result, Parser &P) {
|
|||||||
} else if (P.Tok.getText() == "thunk") {
|
} else if (P.Tok.getText() == "thunk") {
|
||||||
Result = SILLinkage::Thunk;
|
Result = SILLinkage::Thunk;
|
||||||
P.consumeToken(tok::identifier);
|
P.consumeToken(tok::identifier);
|
||||||
|
} else if (P.Tok.getText() == "deserialized") {
|
||||||
|
Result = SILLinkage::Deserialized;
|
||||||
|
P.consumeToken(tok::identifier);
|
||||||
} else {
|
} else {
|
||||||
P.diagnose(P.Tok, diag::expected_sil_linkage_or_function);
|
P.diagnose(P.Tok, diag::expected_sil_linkage_or_function);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1055,6 +1055,9 @@ void SILFunction::print(llvm::raw_ostream &OS, bool Verbose) const {
|
|||||||
break;
|
break;
|
||||||
case SILLinkage::External:
|
case SILLinkage::External:
|
||||||
break;
|
break;
|
||||||
|
case SILLinkage::Deserialized:
|
||||||
|
OS << "deserialized ";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printName(OS);
|
printName(OS);
|
||||||
|
|||||||
@@ -44,29 +44,41 @@ void swift::performSILLinking(SILModule *M) {
|
|||||||
|
|
||||||
while (!Worklist.empty()) {
|
while (!Worklist.empty()) {
|
||||||
auto Fn = Worklist.pop_back_val();
|
auto Fn = Worklist.pop_back_val();
|
||||||
|
|
||||||
for (auto &BB : *Fn) {
|
for (auto &BB : *Fn) {
|
||||||
for (auto I = BB.begin(), E = BB.end(); I != E; I++) {
|
for (auto I = BB.begin(), E = BB.end(); I != E; I++) {
|
||||||
// Handles ApplyInst only.
|
SILFunction *CalleeFunction = nullptr;
|
||||||
auto *AI = dyn_cast<ApplyInst>(I);
|
bool TryLinking = false;
|
||||||
// When EnableLinkAll is true, we don't check whether it is transparent.
|
if (ApplyInst *AI = dyn_cast<ApplyInst>(I)) {
|
||||||
if (!AI || (!EnableLinkAll && !AI->isTransparent()))
|
SILValue Callee = AI->getCallee();
|
||||||
|
// Handles FunctionRefInst only.
|
||||||
|
if (FunctionRefInst *FRI = dyn_cast<FunctionRefInst>(Callee.getDef()))
|
||||||
|
CalleeFunction = FRI->getFunction();
|
||||||
|
|
||||||
|
// When EnableLinkAll is true, we always link the Callee.
|
||||||
|
TryLinking = EnableLinkAll ? true : AI->isTransparent();
|
||||||
|
}
|
||||||
|
else if (SpecializeInst *SI = dyn_cast<SpecializeInst>(I)) {
|
||||||
|
SILValue Callee = SI->getOperand();
|
||||||
|
// Handles FunctionRefInst only.
|
||||||
|
if (FunctionRefInst *FRI = dyn_cast<FunctionRefInst>(Callee.getDef()))
|
||||||
|
CalleeFunction = FRI->getFunction();
|
||||||
|
}
|
||||||
|
if (!CalleeFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SILValue Callee = AI->getCallee();
|
|
||||||
// Handles FunctionRefInst only.
|
|
||||||
FunctionRefInst *FRI = dyn_cast<FunctionRefInst>(Callee.getDef());
|
|
||||||
if (!FRI)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
SILFunction *CalleeFunction = FRI->getFunction();
|
|
||||||
if (CalleeFunction->empty()) {
|
if (CalleeFunction->empty()) {
|
||||||
// Try to find the definition in a serialized module when callee is
|
// Try to find the definition in a serialized module when callee is
|
||||||
// currently empty and the ApplyInst is transparent.
|
// currently empty.
|
||||||
auto NewFn = SILLoader->lookupSILFunction(CalleeFunction);
|
if (TryLinking) {
|
||||||
if (NewFn) {
|
if (auto NewFn = SILLoader->lookupSILFunction(CalleeFunction)) {
|
||||||
Worklist.push_back(NewFn);
|
Worklist.push_back(NewFn);
|
||||||
++NumFuncLinked;
|
++NumFuncLinked;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// FIXME: Make sure the declaration has external linkage?
|
||||||
|
CalleeFunction->setLinkage(SILLinkage::External);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,10 +149,11 @@ Pattern *ModuleFile::maybeReadPattern() {
|
|||||||
ProtocolConformance *
|
ProtocolConformance *
|
||||||
ModuleFile::readUnderlyingConformance(ProtocolDecl *proto,
|
ModuleFile::readUnderlyingConformance(ProtocolDecl *proto,
|
||||||
DeclID typeID,
|
DeclID typeID,
|
||||||
IdentifierID moduleID) {
|
IdentifierID moduleID,
|
||||||
|
llvm::BitstreamCursor &Cursor) {
|
||||||
if (!moduleID) {
|
if (!moduleID) {
|
||||||
// The underlying conformance is in the following record.
|
// The underlying conformance is in the following record.
|
||||||
return maybeReadConformance(getType(typeID))->second;
|
return maybeReadConformance(getType(typeID), Cursor)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dig out the protocol conformance within the nominal declaration.
|
// Dig out the protocol conformance within the nominal declaration.
|
||||||
@@ -187,17 +188,18 @@ ModuleFile::readUnderlyingConformance(ProtocolDecl *proto,
|
|||||||
llvm_unreachable("Unable to find underlying conformance");
|
llvm_unreachable("Unable to find underlying conformance");
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<ConformancePair> ModuleFile::maybeReadConformance(Type conformingType){
|
Optional<ConformancePair> ModuleFile::maybeReadConformance(Type conformingType,
|
||||||
|
llvm::BitstreamCursor &Cursor){
|
||||||
using namespace decls_block;
|
using namespace decls_block;
|
||||||
|
|
||||||
BCOffsetRAII lastRecordOffset(DeclTypeCursor);
|
BCOffsetRAII lastRecordOffset(Cursor);
|
||||||
SmallVector<uint64_t, 16> scratch;
|
SmallVector<uint64_t, 16> scratch;
|
||||||
|
|
||||||
auto next = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
|
auto next = Cursor.advance(AF_DontPopBlockAtEnd);
|
||||||
if (next.Kind != llvm::BitstreamEntry::Record)
|
if (next.Kind != llvm::BitstreamEntry::Record)
|
||||||
return Nothing;
|
return Nothing;
|
||||||
|
|
||||||
unsigned kind = DeclTypeCursor.readRecord(next.ID, scratch);
|
unsigned kind = Cursor.readRecord(next.ID, scratch);
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case NO_CONFORMANCE: {
|
case NO_CONFORMANCE: {
|
||||||
lastRecordOffset.reset();
|
lastRecordOffset.reset();
|
||||||
@@ -231,7 +233,7 @@ Optional<ConformancePair> ModuleFile::maybeReadConformance(Type conformingType){
|
|||||||
// Read the substitutions.
|
// Read the substitutions.
|
||||||
SmallVector<Substitution, 4> substitutions;
|
SmallVector<Substitution, 4> substitutions;
|
||||||
while (numSubstitutions--) {
|
while (numSubstitutions--) {
|
||||||
auto sub = maybeReadSubstitution();
|
auto sub = maybeReadSubstitution(Cursor);
|
||||||
assert(sub.hasValue() && "Missing substitution?");
|
assert(sub.hasValue() && "Missing substitution?");
|
||||||
substitutions.push_back(*sub);
|
substitutions.push_back(*sub);
|
||||||
}
|
}
|
||||||
@@ -243,14 +245,14 @@ Optional<ConformancePair> ModuleFile::maybeReadConformance(Type conformingType){
|
|||||||
// FIXME: We don't actually want to allocate an archetype here; we just
|
// FIXME: We don't actually want to allocate an archetype here; we just
|
||||||
// want to get an access path within the protocol.
|
// want to get an access path within the protocol.
|
||||||
auto first = cast<AssociatedTypeDecl>(getDecl(*rawIDIter++));
|
auto first = cast<AssociatedTypeDecl>(getDecl(*rawIDIter++));
|
||||||
auto second = maybeReadSubstitution();
|
auto second = maybeReadSubstitution(Cursor);
|
||||||
assert(second.hasValue());
|
assert(second.hasValue());
|
||||||
typeWitnesses[first] = *second;
|
typeWitnesses[first] = *second;
|
||||||
}
|
}
|
||||||
assert(rawIDIter <= rawIDs.end() && "read too much");
|
assert(rawIDIter <= rawIDs.end() && "read too much");
|
||||||
|
|
||||||
ProtocolConformance *genericConformance
|
ProtocolConformance *genericConformance
|
||||||
= readUnderlyingConformance(proto, typeID, moduleID);
|
= readUnderlyingConformance(proto, typeID, moduleID, Cursor);
|
||||||
|
|
||||||
// Reset the offset RAII to the end of the trailing records.
|
// Reset the offset RAII to the end of the trailing records.
|
||||||
lastRecordOffset.reset();
|
lastRecordOffset.reset();
|
||||||
@@ -276,7 +278,7 @@ Optional<ConformancePair> ModuleFile::maybeReadConformance(Type conformingType){
|
|||||||
auto proto = cast<ProtocolDecl>(getDecl(protoID));
|
auto proto = cast<ProtocolDecl>(getDecl(protoID));
|
||||||
|
|
||||||
ProtocolConformance *inheritedConformance
|
ProtocolConformance *inheritedConformance
|
||||||
= readUnderlyingConformance(proto, typeID, moduleID);
|
= readUnderlyingConformance(proto, typeID, moduleID, Cursor);
|
||||||
|
|
||||||
// Reset the offset RAII to the end of the trailing records.
|
// Reset the offset RAII to the end of the trailing records.
|
||||||
lastRecordOffset.reset();
|
lastRecordOffset.reset();
|
||||||
@@ -305,7 +307,7 @@ Optional<ConformancePair> ModuleFile::maybeReadConformance(Type conformingType){
|
|||||||
InheritedConformanceMap inheritedConformances;
|
InheritedConformanceMap inheritedConformances;
|
||||||
|
|
||||||
while (inheritedCount--) {
|
while (inheritedCount--) {
|
||||||
auto inherited = maybeReadConformance(conformingType);
|
auto inherited = maybeReadConformance(conformingType, Cursor);
|
||||||
assert(inherited.hasValue());
|
assert(inherited.hasValue());
|
||||||
|
|
||||||
inheritedConformances.insert(inherited.getValue());
|
inheritedConformances.insert(inherited.getValue());
|
||||||
@@ -324,7 +326,7 @@ Optional<ConformancePair> ModuleFile::maybeReadConformance(Type conformingType){
|
|||||||
|
|
||||||
SmallVector<Substitution, 8> substitutions;
|
SmallVector<Substitution, 8> substitutions;
|
||||||
while (substitutionCount--) {
|
while (substitutionCount--) {
|
||||||
auto sub = maybeReadSubstitution();
|
auto sub = maybeReadSubstitution(Cursor);
|
||||||
assert(sub.hasValue());
|
assert(sub.hasValue());
|
||||||
substitutions.push_back(sub.getValue());
|
substitutions.push_back(sub.getValue());
|
||||||
}
|
}
|
||||||
@@ -344,7 +346,7 @@ Optional<ConformancePair> ModuleFile::maybeReadConformance(Type conformingType){
|
|||||||
// FIXME: We don't actually want to allocate an archetype here; we just
|
// FIXME: We don't actually want to allocate an archetype here; we just
|
||||||
// want to get an access path within the protocol.
|
// want to get an access path within the protocol.
|
||||||
auto first = cast<AssociatedTypeDecl>(getDecl(*rawIDIter++));
|
auto first = cast<AssociatedTypeDecl>(getDecl(*rawIDIter++));
|
||||||
auto second = maybeReadSubstitution();
|
auto second = maybeReadSubstitution(Cursor);
|
||||||
assert(second.hasValue());
|
assert(second.hasValue());
|
||||||
typeWitnesses[first] = *second;
|
typeWitnesses[first] = *second;
|
||||||
}
|
}
|
||||||
@@ -387,17 +389,18 @@ void processConformances(ASTContext &ctx, T *decl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Optional<Substitution> ModuleFile::maybeReadSubstitution() {
|
Optional<Substitution> ModuleFile::maybeReadSubstitution(
|
||||||
BCOffsetRAII lastRecordOffset(DeclTypeCursor);
|
llvm::BitstreamCursor &Cursor) {
|
||||||
|
BCOffsetRAII lastRecordOffset(Cursor);
|
||||||
|
|
||||||
auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
|
auto entry = Cursor.advance(AF_DontPopBlockAtEnd);
|
||||||
if (entry.Kind != llvm::BitstreamEntry::Record)
|
if (entry.Kind != llvm::BitstreamEntry::Record)
|
||||||
return Nothing;
|
return Nothing;
|
||||||
|
|
||||||
StringRef blobData;
|
StringRef blobData;
|
||||||
SmallVector<uint64_t, 2> scratch;
|
SmallVector<uint64_t, 2> scratch;
|
||||||
unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch,
|
unsigned recordID = Cursor.readRecord(entry.ID, scratch,
|
||||||
&blobData);
|
&blobData);
|
||||||
if (recordID != decls_block::BOUND_GENERIC_SUBSTITUTION)
|
if (recordID != decls_block::BOUND_GENERIC_SUBSTITUTION)
|
||||||
return Nothing;
|
return Nothing;
|
||||||
|
|
||||||
@@ -416,7 +419,7 @@ Optional<Substitution> ModuleFile::maybeReadSubstitution() {
|
|||||||
|
|
||||||
SmallVector<ProtocolConformance *, 16> conformanceBuf;
|
SmallVector<ProtocolConformance *, 16> conformanceBuf;
|
||||||
while (numConformances--) {
|
while (numConformances--) {
|
||||||
auto conformancePair = maybeReadConformance(replacementTy);
|
auto conformancePair = maybeReadConformance(replacementTy, Cursor);
|
||||||
assert(conformancePair.hasValue() && "Missing conformance");
|
assert(conformancePair.hasValue() && "Missing conformance");
|
||||||
conformanceBuf.push_back(conformancePair->second);
|
conformanceBuf.push_back(conformancePair->second);
|
||||||
}
|
}
|
||||||
@@ -689,7 +692,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
|||||||
alias->setImplicit();
|
alias->setImplicit();
|
||||||
|
|
||||||
SmallVector<ConformancePair, 16> conformances;
|
SmallVector<ConformancePair, 16> conformances;
|
||||||
while (auto conformance = maybeReadConformance(underlyingType.getType()))
|
while (auto conformance = maybeReadConformance(underlyingType.getType(),
|
||||||
|
DeclTypeCursor))
|
||||||
conformances.push_back(*conformance);
|
conformances.push_back(*conformance);
|
||||||
processConformances(ctx, alias, conformances);
|
processConformances(ctx, alias, conformances);
|
||||||
alias->setCheckedInheritanceClause();
|
alias->setCheckedInheritanceClause();
|
||||||
@@ -728,7 +732,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
|||||||
|
|
||||||
SmallVector<ConformancePair, 16> conformances;
|
SmallVector<ConformancePair, 16> conformances;
|
||||||
while (auto conformance
|
while (auto conformance
|
||||||
= maybeReadConformance(genericParam->getDeclaredType()))
|
= maybeReadConformance(genericParam->getDeclaredType(),
|
||||||
|
DeclTypeCursor))
|
||||||
conformances.push_back(*conformance);
|
conformances.push_back(*conformance);
|
||||||
processConformances(ctx, genericParam, conformances);
|
processConformances(ctx, genericParam, conformances);
|
||||||
genericParam->setCheckedInheritanceClause();
|
genericParam->setCheckedInheritanceClause();
|
||||||
@@ -765,7 +770,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
|||||||
|
|
||||||
SmallVector<ConformancePair, 16> conformances;
|
SmallVector<ConformancePair, 16> conformances;
|
||||||
while (auto conformance
|
while (auto conformance
|
||||||
= maybeReadConformance(assocType->getDeclaredType()))
|
= maybeReadConformance(assocType->getDeclaredType(), DeclTypeCursor))
|
||||||
conformances.push_back(*conformance);
|
conformances.push_back(*conformance);
|
||||||
processConformances(ctx, assocType, conformances);
|
processConformances(ctx, assocType, conformances);
|
||||||
assocType->setCheckedInheritanceClause();
|
assocType->setCheckedInheritanceClause();
|
||||||
@@ -805,7 +810,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
|||||||
CanType canTy = theStruct->getDeclaredTypeInContext()->getCanonicalType();
|
CanType canTy = theStruct->getDeclaredTypeInContext()->getCanonicalType();
|
||||||
|
|
||||||
SmallVector<ConformancePair, 16> conformances;
|
SmallVector<ConformancePair, 16> conformances;
|
||||||
while (auto conformance = maybeReadConformance(canTy))
|
while (auto conformance = maybeReadConformance(canTy, DeclTypeCursor))
|
||||||
conformances.push_back(*conformance);
|
conformances.push_back(*conformance);
|
||||||
processConformances(ctx, theStruct, conformances);
|
processConformances(ctx, theStruct, conformances);
|
||||||
|
|
||||||
@@ -1167,7 +1172,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
|||||||
CanType canTy = theClass->getDeclaredTypeInContext()->getCanonicalType();
|
CanType canTy = theClass->getDeclaredTypeInContext()->getCanonicalType();
|
||||||
|
|
||||||
SmallVector<ConformancePair, 16> conformances;
|
SmallVector<ConformancePair, 16> conformances;
|
||||||
while (auto conformance = maybeReadConformance(canTy))
|
while (auto conformance = maybeReadConformance(canTy, DeclTypeCursor))
|
||||||
conformances.push_back(*conformance);
|
conformances.push_back(*conformance);
|
||||||
processConformances(ctx, theClass, conformances);
|
processConformances(ctx, theClass, conformances);
|
||||||
|
|
||||||
@@ -1216,7 +1221,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
|||||||
CanType canTy = theEnum->getDeclaredTypeInContext()->getCanonicalType();
|
CanType canTy = theEnum->getDeclaredTypeInContext()->getCanonicalType();
|
||||||
|
|
||||||
SmallVector<ConformancePair, 16> conformances;
|
SmallVector<ConformancePair, 16> conformances;
|
||||||
while (auto conformance = maybeReadConformance(canTy))
|
while (auto conformance = maybeReadConformance(canTy, DeclTypeCursor))
|
||||||
conformances.push_back(*conformance);
|
conformances.push_back(*conformance);
|
||||||
processConformances(ctx, theEnum, conformances);
|
processConformances(ctx, theEnum, conformances);
|
||||||
|
|
||||||
@@ -1329,7 +1334,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
|||||||
CanType canBaseTy = baseTy.getType()->getCanonicalType();
|
CanType canBaseTy = baseTy.getType()->getCanonicalType();
|
||||||
|
|
||||||
SmallVector<ConformancePair, 16> conformances;
|
SmallVector<ConformancePair, 16> conformances;
|
||||||
while (auto conformance = maybeReadConformance(canBaseTy))
|
while (auto conformance = maybeReadConformance(canBaseTy, DeclTypeCursor))
|
||||||
conformances.push_back(*conformance);
|
conformances.push_back(*conformance);
|
||||||
processConformances(ctx, extension, conformances);
|
processConformances(ctx, extension, conformances);
|
||||||
|
|
||||||
@@ -1959,7 +1964,7 @@ Type ModuleFile::getType(TypeID TID) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
paramList = maybeReadGenericParams(nullptr);
|
paramList = maybeReadGenericParams(ModuleContext);
|
||||||
}
|
}
|
||||||
assert(paramList && "missing generic params for polymorphic function");
|
assert(paramList && "missing generic params for polymorphic function");
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "SILFormat.h"
|
#include "SILFormat.h"
|
||||||
#include "swift/SIL/SILArgument.h"
|
#include "swift/SIL/SILArgument.h"
|
||||||
#include "swift/SIL/SILBuilder.h"
|
#include "swift/SIL/SILBuilder.h"
|
||||||
|
#include "swift/SIL/SILDebugScope.h"
|
||||||
#include "swift/SIL/SILModule.h"
|
#include "swift/SIL/SILModule.h"
|
||||||
#include "swift/Serialization/BCReadingExtras.h"
|
#include "swift/Serialization/BCReadingExtras.h"
|
||||||
|
|
||||||
@@ -244,7 +245,12 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID, SILFunction *InFunc) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto Fn = InFunc;
|
auto Fn = InFunc;
|
||||||
Fn->setLinkage((SILLinkage)Linkage);
|
// FIXME: what should we set the linkage to?
|
||||||
|
Fn->setLinkage(SILLinkage::Deserialized);
|
||||||
|
// FIXME: use the correct SILLocation from module.
|
||||||
|
SourceLoc Loc;
|
||||||
|
Fn->setLocation(SILFileLocation(Loc));
|
||||||
|
Fn->setDebugScope(new (SILMod) SILDebugScope(Fn->getLocation()));
|
||||||
SILBasicBlock *CurrentBB = nullptr;
|
SILBasicBlock *CurrentBB = nullptr;
|
||||||
|
|
||||||
// Clear up at the beginning of each SILFunction.
|
// Clear up at the beginning of each SILFunction.
|
||||||
@@ -1147,16 +1153,16 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
|||||||
case ValueKind::SpecializeInst: {
|
case ValueKind::SpecializeInst: {
|
||||||
// Format: a typed value, a type, a list of substitutions (Archetype name,
|
// Format: a typed value, a type, a list of substitutions (Archetype name,
|
||||||
// Replacement type). Use SILOneTypeValuesLayout.
|
// Replacement type). Use SILOneTypeValuesLayout.
|
||||||
assert(ListOfValues.size() >= 4 &&
|
assert(ListOfValues.size() == 5 && "Expect 5 numbers for SpecializeInst");
|
||||||
"Expect 4 or more numbers for SpecializeInst");
|
unsigned NumSub = ListOfValues[4];
|
||||||
|
// Read the substitutions.
|
||||||
SmallVector<Substitution, 4> Substitutions;
|
SmallVector<Substitution, 4> Substitutions;
|
||||||
for (unsigned I = 4, E = ListOfValues.size(); I < E; I += 2) {
|
while (NumSub--) {
|
||||||
Substitution Sub;
|
auto sub = MF->maybeReadSubstitution(SILCursor);
|
||||||
Sub.Replacement = MF->getType(ListOfValues[I+1]);
|
assert(sub.hasValue() && "Missing substitution?");
|
||||||
Sub.Archetype = cast<ArchetypeType>(
|
Substitutions.push_back(*sub);
|
||||||
MF->getType(ListOfValues[I]).getPointer());
|
|
||||||
Substitutions.push_back(Sub);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ValTy = MF->getType(ListOfValues[0]);
|
auto ValTy = MF->getType(ListOfValues[0]);
|
||||||
assert(ValTy->is<PolymorphicFunctionType>() &&
|
assert(ValTy->is<PolymorphicFunctionType>() &&
|
||||||
"Should be a polymorphic function");
|
"Should be a polymorphic function");
|
||||||
|
|||||||
@@ -222,7 +222,8 @@ private:
|
|||||||
ProtocolConformance *
|
ProtocolConformance *
|
||||||
readUnderlyingConformance(ProtocolDecl *proto,
|
readUnderlyingConformance(ProtocolDecl *proto,
|
||||||
serialization::DeclID typeID,
|
serialization::DeclID typeID,
|
||||||
serialization::IdentifierID moduleID);
|
serialization::IdentifierID moduleID,
|
||||||
|
llvm::BitstreamCursor &Cursor);
|
||||||
|
|
||||||
/// Recursively reads a protocol conformance from \c DeclTypeCursor.
|
/// Recursively reads a protocol conformance from \c DeclTypeCursor.
|
||||||
///
|
///
|
||||||
@@ -232,12 +233,7 @@ private:
|
|||||||
/// If the record at the cursor is not a protocol conformance, returns
|
/// If the record at the cursor is not a protocol conformance, returns
|
||||||
/// Nothing. Note that a null pointer is a valid conformance value.
|
/// Nothing. Note that a null pointer is a valid conformance value.
|
||||||
Optional<std::pair<ProtocolDecl *, ProtocolConformance *>>
|
Optional<std::pair<ProtocolDecl *, ProtocolConformance *>>
|
||||||
maybeReadConformance(Type conformingType);
|
maybeReadConformance(Type conformingType, llvm::BitstreamCursor &Cursor);
|
||||||
|
|
||||||
/// Reads a substitution record from \c DeclTypeCursor.
|
|
||||||
///
|
|
||||||
/// If the record at the cursor is not a substitution, returns Nothing.
|
|
||||||
Optional<Substitution> maybeReadSubstitution();
|
|
||||||
|
|
||||||
/// Reads a generic param list from \c DeclTypeCursor.
|
/// Reads a generic param list from \c DeclTypeCursor.
|
||||||
///
|
///
|
||||||
@@ -389,6 +385,11 @@ public:
|
|||||||
/// If the name matches the name of the current module, a shadowed module
|
/// If the name matches the name of the current module, a shadowed module
|
||||||
/// is loaded instead. An empty name represents the Builtin module.
|
/// is loaded instead. An empty name represents the Builtin module.
|
||||||
Module *getModule(Identifier name);
|
Module *getModule(Identifier name);
|
||||||
|
|
||||||
|
/// Reads a substitution record from \c DeclTypeCursor.
|
||||||
|
///
|
||||||
|
/// If the record at the cursor is not a substitution, returns Nothing.
|
||||||
|
Optional<Substitution> maybeReadSubstitution(llvm::BitstreamCursor &Cursor);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SerializedModule : public LoadedModule {
|
class SerializedModule : public LoadedModule {
|
||||||
|
|||||||
@@ -577,11 +577,12 @@ Serializer::encodeUnderlyingConformance(const ProtocolConformance *conformance,
|
|||||||
void
|
void
|
||||||
Serializer::writeConformance(const ProtocolDecl *protocol,
|
Serializer::writeConformance(const ProtocolDecl *protocol,
|
||||||
const ProtocolConformance *conformance,
|
const ProtocolConformance *conformance,
|
||||||
const Decl *associatedDecl) {
|
const Decl *associatedDecl,
|
||||||
|
const std::array<unsigned, 256> &abbrCodes) {
|
||||||
using namespace decls_block;
|
using namespace decls_block;
|
||||||
|
|
||||||
if (!conformance) {
|
if (!conformance) {
|
||||||
unsigned abbrCode = DeclTypeAbbrCodes[NoConformanceLayout::Code];
|
unsigned abbrCode = abbrCodes[NoConformanceLayout::Code];
|
||||||
NoConformanceLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
NoConformanceLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||||
addDeclRef(protocol));
|
addDeclRef(protocol));
|
||||||
return;
|
return;
|
||||||
@@ -621,7 +622,7 @@ Serializer::writeConformance(const ProtocolDecl *protocol,
|
|||||||
|
|
||||||
unsigned numInheritedConformances = conf->getInheritedConformances().size();
|
unsigned numInheritedConformances = conf->getInheritedConformances().size();
|
||||||
unsigned abbrCode
|
unsigned abbrCode
|
||||||
= DeclTypeAbbrCodes[NormalProtocolConformanceLayout::Code];
|
= abbrCodes[NormalProtocolConformanceLayout::Code];
|
||||||
NormalProtocolConformanceLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
NormalProtocolConformanceLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||||
addDeclRef(protocol),
|
addDeclRef(protocol),
|
||||||
numValueWitnesses,
|
numValueWitnesses,
|
||||||
@@ -637,12 +638,14 @@ Serializer::writeConformance(const ProtocolDecl *protocol,
|
|||||||
inheritedProtos.push_back(inheritedMapping.first);
|
inheritedProtos.push_back(inheritedMapping.first);
|
||||||
inheritedConformance.push_back(inheritedMapping.second);
|
inheritedConformance.push_back(inheritedMapping.second);
|
||||||
}
|
}
|
||||||
writeConformances(inheritedProtos, inheritedConformance, associatedDecl);
|
writeConformances(inheritedProtos, inheritedConformance, associatedDecl,
|
||||||
|
abbrCodes);
|
||||||
for (auto valueMapping : conf->getWitnesses()) {
|
for (auto valueMapping : conf->getWitnesses()) {
|
||||||
writeSubstitutions(valueMapping.second.getSubstitutions());
|
writeSubstitutions(valueMapping.second.getSubstitutions(),
|
||||||
|
abbrCodes);
|
||||||
}
|
}
|
||||||
for (auto typeMapping : conf->getTypeWitnesses())
|
for (auto typeMapping : conf->getTypeWitnesses())
|
||||||
writeSubstitutions(typeMapping.second);
|
writeSubstitutions(typeMapping.second, abbrCodes);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -658,7 +661,7 @@ Serializer::writeConformance(const ProtocolDecl *protocol,
|
|||||||
}
|
}
|
||||||
auto substitutions = conf->getGenericSubstitutions();
|
auto substitutions = conf->getGenericSubstitutions();
|
||||||
unsigned abbrCode
|
unsigned abbrCode
|
||||||
= DeclTypeAbbrCodes[SpecializedProtocolConformanceLayout::Code];
|
= abbrCodes[SpecializedProtocolConformanceLayout::Code];
|
||||||
DeclID typeID;
|
DeclID typeID;
|
||||||
IdentifierID moduleID;
|
IdentifierID moduleID;
|
||||||
|
|
||||||
@@ -674,12 +677,13 @@ Serializer::writeConformance(const ProtocolDecl *protocol,
|
|||||||
numTypeWitnesses,
|
numTypeWitnesses,
|
||||||
substitutions.size(),
|
substitutions.size(),
|
||||||
data);
|
data);
|
||||||
writeSubstitutions(substitutions);
|
writeSubstitutions(substitutions, abbrCodes);
|
||||||
for (auto typeMapping : conf->getTypeWitnesses())
|
for (auto typeMapping : conf->getTypeWitnesses())
|
||||||
writeSubstitutions(typeMapping.second);
|
writeSubstitutions(typeMapping.second, abbrCodes);
|
||||||
|
|
||||||
if (appendGenericConformance) {
|
if (appendGenericConformance) {
|
||||||
writeConformance(protocol, conf->getGenericConformance(), nullptr);
|
writeConformance(protocol, conf->getGenericConformance(), nullptr,
|
||||||
|
abbrCodes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -687,7 +691,7 @@ Serializer::writeConformance(const ProtocolDecl *protocol,
|
|||||||
case ProtocolConformanceKind::Inherited: {
|
case ProtocolConformanceKind::Inherited: {
|
||||||
auto conf = cast<InheritedProtocolConformance>(conformance);
|
auto conf = cast<InheritedProtocolConformance>(conformance);
|
||||||
unsigned abbrCode
|
unsigned abbrCode
|
||||||
= DeclTypeAbbrCodes[InheritedProtocolConformanceLayout::Code];
|
= abbrCodes[InheritedProtocolConformanceLayout::Code];
|
||||||
DeclID typeID;
|
DeclID typeID;
|
||||||
IdentifierID moduleID;
|
IdentifierID moduleID;
|
||||||
|
|
||||||
@@ -701,7 +705,8 @@ Serializer::writeConformance(const ProtocolDecl *protocol,
|
|||||||
typeID,
|
typeID,
|
||||||
moduleID);
|
moduleID);
|
||||||
if (appendInheritedConformance) {
|
if (appendInheritedConformance) {
|
||||||
writeConformance(protocol, conf->getInheritedConformance(), nullptr);
|
writeConformance(protocol, conf->getInheritedConformance(), nullptr,
|
||||||
|
abbrCodes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -711,25 +716,29 @@ Serializer::writeConformance(const ProtocolDecl *protocol,
|
|||||||
void
|
void
|
||||||
Serializer::writeConformances(ArrayRef<ProtocolDecl *> protocols,
|
Serializer::writeConformances(ArrayRef<ProtocolDecl *> protocols,
|
||||||
ArrayRef<ProtocolConformance *> conformances,
|
ArrayRef<ProtocolConformance *> conformances,
|
||||||
const Decl *associatedDecl) {
|
const Decl *associatedDecl,
|
||||||
|
const std::array<unsigned, 256> &abbrCodes) {
|
||||||
using namespace decls_block;
|
using namespace decls_block;
|
||||||
|
|
||||||
for_each(protocols, conformances,
|
for_each(protocols, conformances,
|
||||||
[&](const ProtocolDecl *proto, const ProtocolConformance *conf) {
|
[&](const ProtocolDecl *proto, const ProtocolConformance *conf) {
|
||||||
writeConformance(proto, conf, associatedDecl);
|
writeConformance(proto, conf, associatedDecl, abbrCodes);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Serializer::writeSubstitutions(ArrayRef<Substitution> substitutions) {
|
/// Writes a list of generic substitutions.
|
||||||
|
void Serializer::writeSubstitutions(ArrayRef<Substitution> substitutions,
|
||||||
|
const std::array<unsigned, 256> &abbrCodes) {
|
||||||
using namespace decls_block;
|
using namespace decls_block;
|
||||||
auto abbrCode = DeclTypeAbbrCodes[BoundGenericSubstitutionLayout::Code];
|
auto abbrCode = abbrCodes[BoundGenericSubstitutionLayout::Code];
|
||||||
for (auto &sub : substitutions) {
|
for (auto &sub : substitutions) {
|
||||||
BoundGenericSubstitutionLayout::emitRecord(
|
BoundGenericSubstitutionLayout::emitRecord(
|
||||||
Out, ScratchRecord, abbrCode,
|
Out, ScratchRecord, abbrCode,
|
||||||
addTypeRef(sub.Archetype),
|
addTypeRef(sub.Archetype),
|
||||||
addTypeRef(sub.Replacement),
|
addTypeRef(sub.Replacement),
|
||||||
sub.Archetype->getConformsTo().size());
|
sub.Archetype->getConformsTo().size());
|
||||||
writeConformances(sub.Archetype->getConformsTo(), sub.Conformance);
|
writeConformances(sub.Archetype->getConformsTo(), sub.Conformance, nullptr,
|
||||||
|
abbrCodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -886,7 +895,7 @@ void Serializer::writeDecl(const Decl *D) {
|
|||||||
extension->isImplicit());
|
extension->isImplicit());
|
||||||
|
|
||||||
writeConformances(extension->getProtocols(), extension->getConformances(),
|
writeConformances(extension->getProtocols(), extension->getConformances(),
|
||||||
extension);
|
extension, DeclTypeAbbrCodes);
|
||||||
|
|
||||||
bool isClassExtension = false;
|
bool isClassExtension = false;
|
||||||
if (auto baseNominal = baseTy->getAnyNominal()) {
|
if (auto baseNominal = baseTy->getAnyNominal()) {
|
||||||
@@ -980,7 +989,7 @@ void Serializer::writeDecl(const Decl *D) {
|
|||||||
typeAlias->isImplicit());
|
typeAlias->isImplicit());
|
||||||
|
|
||||||
writeConformances(typeAlias->getProtocols(), typeAlias->getConformances(),
|
writeConformances(typeAlias->getProtocols(), typeAlias->getConformances(),
|
||||||
typeAlias);
|
typeAlias, DeclTypeAbbrCodes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,7 +1014,7 @@ void Serializer::writeDecl(const Decl *D) {
|
|||||||
|
|
||||||
writeConformances(genericParam->getProtocols(),
|
writeConformances(genericParam->getProtocols(),
|
||||||
genericParam->getConformances(),
|
genericParam->getConformances(),
|
||||||
genericParam);
|
genericParam, DeclTypeAbbrCodes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1029,7 +1038,7 @@ void Serializer::writeDecl(const Decl *D) {
|
|||||||
|
|
||||||
writeConformances(assocType->getProtocols(),
|
writeConformances(assocType->getProtocols(),
|
||||||
assocType->getConformances(),
|
assocType->getConformances(),
|
||||||
assocType);
|
assocType, DeclTypeAbbrCodes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1049,7 +1058,7 @@ void Serializer::writeDecl(const Decl *D) {
|
|||||||
|
|
||||||
writeGenericParams(theStruct->getGenericParams());
|
writeGenericParams(theStruct->getGenericParams());
|
||||||
writeConformances(theStruct->getProtocols(), theStruct->getConformances(),
|
writeConformances(theStruct->getProtocols(), theStruct->getConformances(),
|
||||||
theStruct);
|
theStruct, DeclTypeAbbrCodes);
|
||||||
writeMembers(theStruct->getMembers(), false);
|
writeMembers(theStruct->getMembers(), false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1070,7 +1079,7 @@ void Serializer::writeDecl(const Decl *D) {
|
|||||||
|
|
||||||
writeGenericParams(theEnum->getGenericParams());
|
writeGenericParams(theEnum->getGenericParams());
|
||||||
writeConformances(theEnum->getProtocols(), theEnum->getConformances(),
|
writeConformances(theEnum->getProtocols(), theEnum->getConformances(),
|
||||||
theEnum);
|
theEnum, DeclTypeAbbrCodes);
|
||||||
writeMembers(theEnum->getMembers(), false);
|
writeMembers(theEnum->getMembers(), false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1094,7 +1103,7 @@ void Serializer::writeDecl(const Decl *D) {
|
|||||||
|
|
||||||
writeGenericParams(theClass->getGenericParams());
|
writeGenericParams(theClass->getGenericParams());
|
||||||
writeConformances(theClass->getProtocols(), theClass->getConformances(),
|
writeConformances(theClass->getProtocols(), theClass->getConformances(),
|
||||||
theClass);
|
theClass, DeclTypeAbbrCodes);
|
||||||
writeMembers(theClass->getMembers(), true);
|
writeMembers(theClass->getMembers(), true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,9 +172,6 @@ private:
|
|||||||
/// Writes a generic parameter list.
|
/// Writes a generic parameter list.
|
||||||
bool writeGenericParams(const GenericParamList *genericParams);
|
bool writeGenericParams(const GenericParamList *genericParams);
|
||||||
|
|
||||||
/// Writes a list of generic substitutions.
|
|
||||||
void writeSubstitutions(ArrayRef<Substitution> substitutions);
|
|
||||||
|
|
||||||
/// Encode the underlying conformance of a generic or specialized
|
/// Encode the underlying conformance of a generic or specialized
|
||||||
/// conformance.
|
/// conformance.
|
||||||
///
|
///
|
||||||
@@ -195,12 +192,14 @@ private:
|
|||||||
/// Writes a protocol conformance.
|
/// Writes a protocol conformance.
|
||||||
void writeConformance(const ProtocolDecl *protocol,
|
void writeConformance(const ProtocolDecl *protocol,
|
||||||
const ProtocolConformance *conformance,
|
const ProtocolConformance *conformance,
|
||||||
const Decl *associatedDecl);
|
const Decl *associatedDecl,
|
||||||
|
const std::array<unsigned, 256> &abbrCodes);
|
||||||
|
|
||||||
/// Writes a list of protocol conformances.
|
/// Writes a list of protocol conformances.
|
||||||
void writeConformances(ArrayRef<ProtocolDecl *> protocols,
|
void writeConformances(ArrayRef<ProtocolDecl *> protocols,
|
||||||
ArrayRef<ProtocolConformance *> conformances,
|
ArrayRef<ProtocolConformance *> conformances,
|
||||||
const Decl *associatedDecl = nullptr);
|
const Decl *associatedDecl,
|
||||||
|
const std::array<unsigned, 256> &abbrCodes);
|
||||||
|
|
||||||
/// Writes an array of members for a decl context.
|
/// Writes an array of members for a decl context.
|
||||||
///
|
///
|
||||||
@@ -291,6 +290,11 @@ public:
|
|||||||
/// \returns The ID for the identifier for the module's name, or 0 for the
|
/// \returns The ID for the identifier for the module's name, or 0 for the
|
||||||
/// builtin module.
|
/// builtin module.
|
||||||
IdentifierID addModuleRef(const Module *M);
|
IdentifierID addModuleRef(const Module *M);
|
||||||
|
|
||||||
|
/// Writes a list of generic substitutions. abbrCode is needed to support
|
||||||
|
/// usage out of decl block.
|
||||||
|
void writeSubstitutions(ArrayRef<Substitution> substitutions,
|
||||||
|
const std::array<unsigned, 256> &abbrCodes);
|
||||||
};
|
};
|
||||||
} // end namespace serialization
|
} // end namespace serialization
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|||||||
@@ -1055,16 +1055,14 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
|
|||||||
ListOfValues.push_back((unsigned)SpI->getOperand().getType().getCategory());
|
ListOfValues.push_back((unsigned)SpI->getOperand().getType().getCategory());
|
||||||
ListOfValues.push_back(addValueRef(SpI->getOperand()));
|
ListOfValues.push_back(addValueRef(SpI->getOperand()));
|
||||||
ListOfValues.push_back(SpI->getOperand().getResultNumber());
|
ListOfValues.push_back(SpI->getOperand().getResultNumber());
|
||||||
|
ListOfValues.push_back(SpI->getSubstitutions().size());
|
||||||
for (auto Sub : SpI->getSubstitutions()) {
|
|
||||||
ListOfValues.push_back(S.addTypeRef(Sub.Archetype));
|
|
||||||
ListOfValues.push_back(S.addTypeRef(Sub.Replacement));
|
|
||||||
}
|
|
||||||
|
|
||||||
SILOneTypeValuesLayout::emitRecord(Out, ScratchRecord,
|
SILOneTypeValuesLayout::emitRecord(Out, ScratchRecord,
|
||||||
SILAbbrCodes[SILOneTypeValuesLayout::Code], (unsigned)SI.getKind(),
|
SILAbbrCodes[SILOneTypeValuesLayout::Code], (unsigned)SI.getKind(),
|
||||||
S.addTypeRef(SpI->getType().getSwiftRValueType()),
|
S.addTypeRef(SpI->getType().getSwiftRValueType()),
|
||||||
(unsigned)SpI->getType().getCategory(), ListOfValues);
|
(unsigned)SpI->getType().getCategory(), ListOfValues);
|
||||||
|
|
||||||
|
S.writeSubstitutions(SpI->getSubstitutions(), SILAbbrCodes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1105,7 +1103,7 @@ void SILSerializer::writeFuncTable() {
|
|||||||
|
|
||||||
void SILSerializer::writeAllSILFunctions(const SILModule *M) {
|
void SILSerializer::writeAllSILFunctions(const SILModule *M) {
|
||||||
{
|
{
|
||||||
BCBlockRAII subBlock(Out, SIL_BLOCK_ID, 4);
|
BCBlockRAII subBlock(Out, SIL_BLOCK_ID, 5);
|
||||||
registerSILAbbr<SILFunctionLayout>();
|
registerSILAbbr<SILFunctionLayout>();
|
||||||
registerSILAbbr<SILBasicBlockLayout>();
|
registerSILAbbr<SILBasicBlockLayout>();
|
||||||
registerSILAbbr<SILOneValueOneOperandLayout>();
|
registerSILAbbr<SILOneValueOneOperandLayout>();
|
||||||
@@ -1117,6 +1115,16 @@ void SILSerializer::writeAllSILFunctions(const SILModule *M) {
|
|||||||
registerSILAbbr<SILInstApplyLayout>();
|
registerSILAbbr<SILInstApplyLayout>();
|
||||||
registerSILAbbr<SILInstNoOperandLayout>();
|
registerSILAbbr<SILInstNoOperandLayout>();
|
||||||
|
|
||||||
|
// Register the abbreviation codes so these layouts can exist in both
|
||||||
|
// decl blocks and sil blocks.
|
||||||
|
// We have to make sure BOUND_GENERIC_SUBSTITUTION does not overlap with
|
||||||
|
// SIL-specific records.
|
||||||
|
registerSILAbbr<decls_block::BoundGenericSubstitutionLayout>();
|
||||||
|
registerSILAbbr<decls_block::NoConformanceLayout>();
|
||||||
|
registerSILAbbr<decls_block::NormalProtocolConformanceLayout>();
|
||||||
|
registerSILAbbr<decls_block::SpecializedProtocolConformanceLayout>();
|
||||||
|
registerSILAbbr<decls_block::InheritedProtocolConformanceLayout>();
|
||||||
|
|
||||||
// Go through all SILFunctions in M, and if it is transparent,
|
// Go through all SILFunctions in M, and if it is transparent,
|
||||||
// write out the SILFunction.
|
// write out the SILFunction.
|
||||||
if (M && (EnableSerialize || EnableSerializeAll)) {
|
if (M && (EnableSerialize || EnableSerializeAll)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user