mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
507 lines
20 KiB
C++
507 lines
20 KiB
C++
//===--- SerializeSILPass.cpp ---------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define DEBUG_TYPE "serialize-sil"
|
|
#include "swift/Strings.h"
|
|
#include "swift/SIL/ApplySite.h"
|
|
#include "swift/SIL/SILCloner.h"
|
|
#include "swift/SIL/SILFunction.h"
|
|
#include "swift/SILOptimizer/PassManager/Passes.h"
|
|
#include "swift/SILOptimizer/PassManager/Transforms.h"
|
|
#include "swift/SILOptimizer/Utils/BasicBlockOptUtils.h"
|
|
|
|
using namespace swift;
|
|
|
|
namespace {
|
|
/// In place map opaque archetypes to their underlying type in a function.
|
|
/// This needs to happen when a function changes from serializable to not
|
|
/// serializable.
|
|
class MapOpaqueArchetypes : public SILCloner<MapOpaqueArchetypes> {
|
|
using SuperTy = SILCloner<MapOpaqueArchetypes>;
|
|
|
|
SILBasicBlock *origEntryBlock;
|
|
SILBasicBlock *clonedEntryBlock;
|
|
public:
|
|
friend class SILCloner<MapOpaqueArchetypes>;
|
|
friend class SILCloner<MapOpaqueArchetypes>;
|
|
friend class SILInstructionVisitor<MapOpaqueArchetypes>;
|
|
|
|
MapOpaqueArchetypes(SILFunction &fun) : SuperTy(fun) {
|
|
origEntryBlock = fun.getEntryBlock();
|
|
clonedEntryBlock = fun.createBasicBlock();
|
|
}
|
|
|
|
bool shouldSubstOpaqueArchetypes() const { return true; }
|
|
|
|
void replace();
|
|
};
|
|
} // namespace
|
|
|
|
void MapOpaqueArchetypes::replace() {
|
|
// Map the function arguments.
|
|
SmallVector<SILValue, 4> entryArgs;
|
|
entryArgs.reserve(origEntryBlock->getArguments().size());
|
|
for (auto &origArg : origEntryBlock->getArguments()) {
|
|
SILType mappedType = remapType(origArg->getType());
|
|
auto *NewArg = clonedEntryBlock->createFunctionArgument(
|
|
mappedType, origArg->getDecl(), true);
|
|
NewArg->copyFlags(cast<SILFunctionArgument>(origArg));
|
|
entryArgs.push_back(NewArg);
|
|
}
|
|
|
|
getBuilder().setInsertionPoint(clonedEntryBlock);
|
|
auto &fn = getBuilder().getFunction();
|
|
cloneFunctionBody(&fn, clonedEntryBlock, entryArgs,
|
|
true /*replaceOriginalFunctionInPlace*/);
|
|
// Insert the new entry block at the beginning.
|
|
fn.moveBlockBefore(clonedEntryBlock, fn.begin());
|
|
removeUnreachableBlocks(fn);
|
|
}
|
|
|
|
static bool opaqueArchetypeWouldChange(TypeExpansionContext context,
|
|
CanType ty) {
|
|
if (!ty->hasOpaqueArchetype())
|
|
return false;
|
|
|
|
return ty.findIf([=](Type type) -> bool {
|
|
if (auto opaqueTy = type->getAs<OpaqueTypeArchetypeType>()) {
|
|
auto opaque = opaqueTy->getDecl();
|
|
auto module = context.getContext()->getParentModule();
|
|
OpaqueSubstitutionKind subKind =
|
|
ReplaceOpaqueTypesWithUnderlyingTypes::shouldPerformSubstitution(
|
|
opaque, module, context.getResilienceExpansion());
|
|
return subKind != OpaqueSubstitutionKind::DontSubstitute;
|
|
}
|
|
return false;
|
|
});
|
|
}
|
|
|
|
static bool hasOpaqueArchetypeOperand(TypeExpansionContext context,
|
|
SILInstruction &inst) {
|
|
// Check the operands for opaque types.
|
|
for (auto &opd : inst.getAllOperands())
|
|
if (opaqueArchetypeWouldChange(context, opd.get()->getType().getASTType()))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
static bool hasOpaqueArchetypeResult(TypeExpansionContext context,
|
|
SILInstruction &inst) {
|
|
// Check the results for opaque types.
|
|
for (SILValue res : inst.getResults())
|
|
if (opaqueArchetypeWouldChange(context, res->getType().getASTType()))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
static bool hasOpaqueArchetype(TypeExpansionContext context,
|
|
SILInstruction &inst) {
|
|
// Check operands and results.
|
|
if (hasOpaqueArchetypeOperand(context, inst))
|
|
return true;
|
|
if (hasOpaqueArchetypeResult(context, inst))
|
|
return true;
|
|
|
|
// Check substitution maps.
|
|
switch (inst.getKind()) {
|
|
case SILInstructionKind::AllocStackInst:
|
|
case SILInstructionKind::AllocPackInst:
|
|
case SILInstructionKind::AllocPackMetadataInst:
|
|
case SILInstructionKind::AllocRefInst:
|
|
case SILInstructionKind::AllocRefDynamicInst:
|
|
case SILInstructionKind::AllocBoxInst:
|
|
case SILInstructionKind::AllocExistentialBoxInst:
|
|
case SILInstructionKind::IndexAddrInst:
|
|
case SILInstructionKind::TailAddrInst:
|
|
case SILInstructionKind::IndexRawPointerInst:
|
|
case SILInstructionKind::FunctionRefInst:
|
|
case SILInstructionKind::DynamicFunctionRefInst:
|
|
case SILInstructionKind::PreviousDynamicFunctionRefInst:
|
|
case SILInstructionKind::GlobalAddrInst:
|
|
case SILInstructionKind::GlobalValueInst:
|
|
case SILInstructionKind::BaseAddrForOffsetInst:
|
|
case SILInstructionKind::IntegerLiteralInst:
|
|
case SILInstructionKind::FloatLiteralInst:
|
|
case SILInstructionKind::StringLiteralInst:
|
|
case SILInstructionKind::ClassMethodInst:
|
|
case SILInstructionKind::SuperMethodInst:
|
|
case SILInstructionKind::ObjCMethodInst:
|
|
case SILInstructionKind::ObjCSuperMethodInst:
|
|
case SILInstructionKind::WitnessMethodInst:
|
|
case SILInstructionKind::UpcastInst:
|
|
case SILInstructionKind::AddressToPointerInst:
|
|
case SILInstructionKind::PointerToAddressInst:
|
|
case SILInstructionKind::UncheckedRefCastInst:
|
|
case SILInstructionKind::UncheckedAddrCastInst:
|
|
case SILInstructionKind::UncheckedTrivialBitCastInst:
|
|
case SILInstructionKind::UncheckedBitwiseCastInst:
|
|
case SILInstructionKind::UncheckedValueCastInst:
|
|
case SILInstructionKind::RefToRawPointerInst:
|
|
case SILInstructionKind::RawPointerToRefInst:
|
|
#define LOADABLE_REF_STORAGE(Name, ...) \
|
|
case SILInstructionKind::RefTo##Name##Inst: \
|
|
case SILInstructionKind::Name##ToRefInst:
|
|
#include "swift/AST/ReferenceStorage.def"
|
|
#undef LOADABLE_REF_STORAGE_HELPER
|
|
case SILInstructionKind::ConvertFunctionInst:
|
|
case SILInstructionKind::ConvertEscapeToNoEscapeInst:
|
|
case SILInstructionKind::RefToBridgeObjectInst:
|
|
case SILInstructionKind::BridgeObjectToRefInst:
|
|
case SILInstructionKind::BridgeObjectToWordInst:
|
|
case SILInstructionKind::ThinToThickFunctionInst:
|
|
case SILInstructionKind::ThickToObjCMetatypeInst:
|
|
case SILInstructionKind::ObjCToThickMetatypeInst:
|
|
case SILInstructionKind::ObjCMetatypeToObjectInst:
|
|
case SILInstructionKind::ObjCExistentialMetatypeToObjectInst:
|
|
case SILInstructionKind::UnconditionalCheckedCastInst:
|
|
case SILInstructionKind::ClassifyBridgeObjectInst:
|
|
case SILInstructionKind::ValueToBridgeObjectInst:
|
|
case SILInstructionKind::MarkDependenceInst:
|
|
case SILInstructionKind::MarkDependenceAddrInst:
|
|
case SILInstructionKind::MergeIsolationRegionInst:
|
|
case SILInstructionKind::CopyBlockInst:
|
|
case SILInstructionKind::CopyBlockWithoutEscapingInst:
|
|
case SILInstructionKind::CopyValueInst:
|
|
case SILInstructionKind::ExplicitCopyValueInst:
|
|
case SILInstructionKind::MoveValueInst:
|
|
case SILInstructionKind::DropDeinitInst:
|
|
case SILInstructionKind::MarkUnresolvedNonCopyableValueInst:
|
|
case SILInstructionKind::MarkUnresolvedReferenceBindingInst:
|
|
case SILInstructionKind::CopyableToMoveOnlyWrapperValueInst:
|
|
case SILInstructionKind::MoveOnlyWrapperToCopyableValueInst:
|
|
case SILInstructionKind::UnownedCopyValueInst:
|
|
case SILInstructionKind::WeakCopyValueInst:
|
|
#define REF_STORAGE(Name, ...) \
|
|
case SILInstructionKind::StrongCopy##Name##ValueInst:
|
|
#include "swift/AST/ReferenceStorage.def"
|
|
case SILInstructionKind::UncheckedOwnershipConversionInst:
|
|
case SILInstructionKind::IsUniqueInst:
|
|
case SILInstructionKind::DestroyNotEscapedClosureInst:
|
|
case SILInstructionKind::LoadInst:
|
|
case SILInstructionKind::LoadBorrowInst:
|
|
case SILInstructionKind::BeginBorrowInst:
|
|
case SILInstructionKind::BorrowedFromInst:
|
|
case SILInstructionKind::StoreBorrowInst:
|
|
case SILInstructionKind::BeginAccessInst:
|
|
case SILInstructionKind::MoveOnlyWrapperToCopyableAddrInst:
|
|
case SILInstructionKind::MoveOnlyWrapperToCopyableBoxInst:
|
|
case SILInstructionKind::CopyableToMoveOnlyWrapperAddrInst:
|
|
#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
|
|
case SILInstructionKind::Load##Name##Inst:
|
|
#include "swift/AST/ReferenceStorage.def"
|
|
#undef NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
|
|
case SILInstructionKind::MarkUninitializedInst:
|
|
case SILInstructionKind::ProjectBoxInst:
|
|
case SILInstructionKind::ProjectExistentialBoxInst:
|
|
case SILInstructionKind::BuiltinInst:
|
|
case SILInstructionKind::MetatypeInst:
|
|
case SILInstructionKind::ValueMetatypeInst:
|
|
case SILInstructionKind::ExistentialMetatypeInst:
|
|
case SILInstructionKind::ObjCProtocolInst:
|
|
case SILInstructionKind::ObjectInst:
|
|
case SILInstructionKind::VectorInst:
|
|
case SILInstructionKind::VectorBaseAddrInst:
|
|
case SILInstructionKind::TupleInst:
|
|
case SILInstructionKind::TupleAddrConstructorInst:
|
|
case SILInstructionKind::TupleExtractInst:
|
|
case SILInstructionKind::TuplePackExtractInst:
|
|
case SILInstructionKind::TupleElementAddrInst:
|
|
case SILInstructionKind::StructInst:
|
|
case SILInstructionKind::StructExtractInst:
|
|
case SILInstructionKind::StructElementAddrInst:
|
|
case SILInstructionKind::RefElementAddrInst:
|
|
case SILInstructionKind::RefTailAddrInst:
|
|
case SILInstructionKind::EnumInst:
|
|
case SILInstructionKind::UncheckedEnumDataInst:
|
|
case SILInstructionKind::InitEnumDataAddrInst:
|
|
case SILInstructionKind::UncheckedTakeEnumDataAddrInst:
|
|
case SILInstructionKind::SelectEnumInst:
|
|
case SILInstructionKind::SelectEnumAddrInst:
|
|
case SILInstructionKind::InitExistentialAddrInst:
|
|
case SILInstructionKind::InitExistentialValueInst:
|
|
case SILInstructionKind::OpenExistentialAddrInst:
|
|
case SILInstructionKind::InitExistentialRefInst:
|
|
case SILInstructionKind::OpenExistentialRefInst:
|
|
case SILInstructionKind::InitExistentialMetatypeInst:
|
|
case SILInstructionKind::OpenExistentialMetatypeInst:
|
|
case SILInstructionKind::OpenExistentialBoxInst:
|
|
case SILInstructionKind::OpenExistentialValueInst:
|
|
case SILInstructionKind::OpenExistentialBoxValueInst:
|
|
case SILInstructionKind::ProjectBlockStorageInst:
|
|
case SILInstructionKind::InitBlockStorageHeaderInst:
|
|
case SILInstructionKind::KeyPathInst:
|
|
case SILInstructionKind::UnreachableInst:
|
|
case SILInstructionKind::ReturnInst:
|
|
case SILInstructionKind::ThrowInst:
|
|
case SILInstructionKind::ThrowAddrInst:
|
|
case SILInstructionKind::YieldInst:
|
|
case SILInstructionKind::UnwindInst:
|
|
case SILInstructionKind::BranchInst:
|
|
case SILInstructionKind::CondBranchInst:
|
|
case SILInstructionKind::SwitchValueInst:
|
|
case SILInstructionKind::SwitchEnumInst:
|
|
case SILInstructionKind::SwitchEnumAddrInst:
|
|
case SILInstructionKind::DynamicMethodBranchInst:
|
|
case SILInstructionKind::CheckedCastBranchInst:
|
|
case SILInstructionKind::CheckedCastAddrBranchInst:
|
|
case SILInstructionKind::DeallocStackInst:
|
|
case SILInstructionKind::DeallocStackRefInst:
|
|
case SILInstructionKind::DeallocPackInst:
|
|
case SILInstructionKind::DeallocPackMetadataInst:
|
|
case SILInstructionKind::DeallocRefInst:
|
|
case SILInstructionKind::DeallocPartialRefInst:
|
|
case SILInstructionKind::DeallocBoxInst:
|
|
case SILInstructionKind::DeallocExistentialBoxInst:
|
|
case SILInstructionKind::StrongRetainInst:
|
|
case SILInstructionKind::StrongReleaseInst:
|
|
case SILInstructionKind::UnmanagedRetainValueInst:
|
|
case SILInstructionKind::UnmanagedReleaseValueInst:
|
|
case SILInstructionKind::UnmanagedAutoreleaseValueInst:
|
|
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
|
|
case SILInstructionKind::StrongRetain##Name##Inst: \
|
|
case SILInstructionKind::Name##RetainInst: \
|
|
case SILInstructionKind::Name##ReleaseInst:
|
|
#include "swift/AST/ReferenceStorage.def"
|
|
#undef ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE
|
|
case SILInstructionKind::RetainValueInst:
|
|
case SILInstructionKind::RetainValueAddrInst:
|
|
case SILInstructionKind::ReleaseValueInst:
|
|
case SILInstructionKind::ReleaseValueAddrInst:
|
|
case SILInstructionKind::BeginDeallocRefInst:
|
|
case SILInstructionKind::EndInitLetRefInst:
|
|
case SILInstructionKind::AutoreleaseValueInst:
|
|
case SILInstructionKind::BindMemoryInst:
|
|
case SILInstructionKind::RebindMemoryInst:
|
|
case SILInstructionKind::FixLifetimeInst:
|
|
case SILInstructionKind::DestroyValueInst:
|
|
case SILInstructionKind::EndBorrowInst:
|
|
case SILInstructionKind::EndAccessInst:
|
|
case SILInstructionKind::BeginUnpairedAccessInst:
|
|
case SILInstructionKind::EndUnpairedAccessInst:
|
|
case SILInstructionKind::StoreInst:
|
|
case SILInstructionKind::AssignInst:
|
|
case SILInstructionKind::AssignOrInitInst:
|
|
case SILInstructionKind::MarkFunctionEscapeInst:
|
|
case SILInstructionKind::DebugValueInst:
|
|
case SILInstructionKind::DebugStepInst:
|
|
case SILInstructionKind::SpecifyTestInst:
|
|
#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
|
|
case SILInstructionKind::Store##Name##Inst:
|
|
#include "swift/AST/ReferenceStorage.def"
|
|
case SILInstructionKind::CopyAddrInst:
|
|
case SILInstructionKind::ExplicitCopyAddrInst:
|
|
case SILInstructionKind::MarkUnresolvedMoveAddrInst:
|
|
case SILInstructionKind::DestroyAddrInst:
|
|
case SILInstructionKind::EndLifetimeInst:
|
|
case SILInstructionKind::ExtendLifetimeInst:
|
|
case SILInstructionKind::InjectEnumAddrInst:
|
|
case SILInstructionKind::DeinitExistentialAddrInst:
|
|
case SILInstructionKind::DeinitExistentialValueInst:
|
|
case SILInstructionKind::UnconditionalCheckedCastAddrInst:
|
|
case SILInstructionKind::UncheckedRefCastAddrInst:
|
|
case SILInstructionKind::AllocGlobalInst:
|
|
case SILInstructionKind::EndApplyInst:
|
|
case SILInstructionKind::AbortApplyInst:
|
|
case SILInstructionKind::CondFailInst:
|
|
case SILInstructionKind::DestructureStructInst:
|
|
case SILInstructionKind::DestructureTupleInst:
|
|
case SILInstructionKind::DifferentiableFunctionInst:
|
|
case SILInstructionKind::DifferentiableFunctionExtractInst:
|
|
case SILInstructionKind::LinearFunctionInst:
|
|
case SILInstructionKind::LinearFunctionExtractInst:
|
|
case SILInstructionKind::DifferentiabilityWitnessFunctionInst:
|
|
case SILInstructionKind::BeginCOWMutationInst:
|
|
case SILInstructionKind::EndCOWMutationInst:
|
|
case SILInstructionKind::EndCOWMutationAddrInst:
|
|
case SILInstructionKind::IncrementProfilerCounterInst:
|
|
case SILInstructionKind::GetAsyncContinuationInst:
|
|
case SILInstructionKind::GetAsyncContinuationAddrInst:
|
|
case SILInstructionKind::AwaitAsyncContinuationInst:
|
|
case SILInstructionKind::HopToExecutorInst:
|
|
case SILInstructionKind::ExtractExecutorInst:
|
|
case SILInstructionKind::FunctionExtractIsolationInst:
|
|
case SILInstructionKind::HasSymbolInst:
|
|
case SILInstructionKind::PackElementGetInst:
|
|
case SILInstructionKind::PackElementSetInst:
|
|
case SILInstructionKind::TuplePackElementAddrInst:
|
|
case SILInstructionKind::TypeValueInst:
|
|
case SILInstructionKind::IgnoredUseInst:
|
|
// Handle by operand and result check.
|
|
break;
|
|
|
|
case SILInstructionKind::PackLengthInst:
|
|
// We reduce the pack shape, so it would very odd if this pack had
|
|
// opaque archetypes in it, but there's no harm in doing it right.
|
|
return opaqueArchetypeWouldChange(context,
|
|
cast<PackLengthInst>(&inst)->getPackType());
|
|
|
|
case SILInstructionKind::DynamicPackIndexInst:
|
|
case SILInstructionKind::PackPackIndexInst:
|
|
case SILInstructionKind::ScalarPackIndexInst:
|
|
return opaqueArchetypeWouldChange(context,
|
|
cast<AnyPackIndexInst>(&inst)->getIndexedPackType());
|
|
|
|
case SILInstructionKind::OpenPackElementInst: {
|
|
auto open = cast<OpenPackElementInst>(&inst);
|
|
bool wouldChange = false;
|
|
open->getOpenedGenericEnvironment()
|
|
->forEachPackElementBinding([&](ElementArchetypeType *elementType,
|
|
PackType *packSubstitution) {
|
|
if (!wouldChange) {
|
|
if (opaqueArchetypeWouldChange(context,
|
|
packSubstitution->getCanonicalType()))
|
|
wouldChange = true;
|
|
}
|
|
});
|
|
return wouldChange;
|
|
}
|
|
|
|
case SILInstructionKind::ThunkInst: {
|
|
auto subs = cast<ThunkInst>(&inst)->getSubstitutionMap();
|
|
for (auto ty : subs.getReplacementTypes()) {
|
|
if (opaqueArchetypeWouldChange(context, ty->getCanonicalType()))
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SILInstructionKind::ApplyInst:
|
|
case SILInstructionKind::PartialApplyInst:
|
|
case SILInstructionKind::TryApplyInst:
|
|
case SILInstructionKind::BeginApplyInst:
|
|
// Check substitution map.
|
|
auto apply = ApplySite(&inst);
|
|
auto subs = apply.getSubstitutionMap();
|
|
for (auto ty: subs.getReplacementTypes()) {
|
|
if (opaqueArchetypeWouldChange(context, ty->getCanonicalType()))
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static bool hasOpaqueArchetypeArgument(TypeExpansionContext context, SILBasicBlock &BB) {
|
|
for (auto *arg : BB.getArguments()) {
|
|
if (opaqueArchetypeWouldChange(context, arg->getType().getASTType()))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool hasAnyOpaqueArchetype(SILFunction &F) {
|
|
bool foundOpaqueArchetype = false;
|
|
auto context = F.getTypeExpansionContext();
|
|
for (auto &BB : F) {
|
|
// Check basic block argument types.
|
|
if (hasOpaqueArchetypeArgument(context, BB)) {
|
|
foundOpaqueArchetype = true;
|
|
break;
|
|
}
|
|
|
|
// Check instruction results and operands.
|
|
for (auto &inst : BB) {
|
|
if (hasOpaqueArchetype(context, inst)) {
|
|
foundOpaqueArchetype = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (foundOpaqueArchetype)
|
|
break;
|
|
}
|
|
|
|
return foundOpaqueArchetype;
|
|
}
|
|
|
|
void updateOpaqueArchetypes(SILFunction &F) {
|
|
// Only map if there are opaque archetypes that could change.
|
|
if (!hasAnyOpaqueArchetype(F))
|
|
return;
|
|
|
|
MapOpaqueArchetypes(F).replace();
|
|
}
|
|
|
|
/// A utility pass to serialize a SILModule at any place inside the optimization
|
|
/// pipeline.
|
|
class SerializeSILPass : public SILModuleTransform {
|
|
|
|
/// Removes [serialized] from all functions. This allows for more
|
|
/// optimizations and for a better dead function elimination.
|
|
void removeSerializedFlagFromAllFunctions(SILModule &M) {
|
|
for (auto &F : M) {
|
|
bool wasSerialized = F.isAnySerialized();
|
|
F.setSerializedKind(IsNotSerialized);
|
|
|
|
// We are removing [serialized] from the function. This will change how
|
|
// opaque archetypes are lowered in SIL - they might lower to their
|
|
// underlying type. Update the function's opaque archetypes.
|
|
if (wasSerialized && F.isDefinition()) {
|
|
updateOpaqueArchetypes(F);
|
|
invalidateAnalysis(&F, SILAnalysis::InvalidationKind::FunctionBody);
|
|
}
|
|
|
|
// After serialization we don't need to keep @alwaysEmitIntoClient
|
|
// functions alive, i.e. we don't need to treat them as public functions.
|
|
if (M.isWholeModule()) {
|
|
switch (F.getLinkage()) {
|
|
case SILLinkage::PublicNonABI:
|
|
case SILLinkage::PackageNonABI:
|
|
F.setLinkage(SILLinkage::Shared);
|
|
break;
|
|
case SILLinkage::Public:
|
|
case SILLinkage::Package:
|
|
case SILLinkage::Hidden:
|
|
case SILLinkage::Shared:
|
|
case SILLinkage::Private:
|
|
case SILLinkage::PublicExternal:
|
|
case SILLinkage::PackageExternal:
|
|
case SILLinkage::HiddenExternal:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (auto &WT : M.getWitnessTables()) {
|
|
WT.setSerializedKind(IsNotSerialized);
|
|
}
|
|
|
|
for (auto &VT : M.getVTables()) {
|
|
VT->setSerializedKind(IsNotSerialized);
|
|
}
|
|
|
|
for (auto &Deinit : M.getMoveOnlyDeinits()) {
|
|
Deinit->setSerializedKind(IsNotSerialized);
|
|
}
|
|
}
|
|
|
|
public:
|
|
SerializeSILPass() {}
|
|
|
|
void run() override {
|
|
auto &M = *getModule();
|
|
// Nothing to do if the module was serialized already.
|
|
if (M.isSerialized())
|
|
return;
|
|
|
|
LLVM_DEBUG(llvm::dbgs() << "Serializing SILModule in SerializeSILPass\n");
|
|
M.serialize();
|
|
|
|
removeSerializedFlagFromAllFunctions(M);
|
|
}
|
|
};
|
|
|
|
SILTransform *swift::createSerializeSILPass() {
|
|
return new SerializeSILPass();
|
|
}
|