mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Embedded] Introduce DeferredCodeGen feature.
Introduce an experimental feature DeferredCodeGen, that defers the generation of LLVM IR (and therefore object code) for all entities within an Embedded Swift module unless they have explicitly requested to not be emitted into the client (e.g., with `@_neverEmitIntoClient`). This feature is meant to generalize and subsume -emit-empty-object-file, relying on lazy emission of entities rather than abruptly ending the compilation pipeline before emitting any IR. Part of rdar://158363967.
This commit is contained in:
@@ -752,7 +752,7 @@ protected:
|
|||||||
HasAnyUnavailableDuringLoweringValues : 1
|
HasAnyUnavailableDuringLoweringValues : 1
|
||||||
);
|
);
|
||||||
|
|
||||||
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8,
|
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8,
|
||||||
/// If the module is compiled as static library.
|
/// If the module is compiled as static library.
|
||||||
StaticLibrary : 1,
|
StaticLibrary : 1,
|
||||||
|
|
||||||
@@ -821,7 +821,10 @@ protected:
|
|||||||
SerializePackageEnabled : 1,
|
SerializePackageEnabled : 1,
|
||||||
|
|
||||||
/// Whether this module has enabled strict memory safety checking.
|
/// Whether this module has enabled strict memory safety checking.
|
||||||
StrictMemorySafety : 1
|
StrictMemorySafety : 1,
|
||||||
|
|
||||||
|
/// Whether this module uses deferred code generation in Embedded Swift.
|
||||||
|
DeferredCodeGen : 1
|
||||||
);
|
);
|
||||||
|
|
||||||
SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,
|
SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,
|
||||||
|
|||||||
@@ -818,7 +818,7 @@ public:
|
|||||||
Bits.ModuleDecl.IsConcurrencyChecked = value;
|
Bits.ModuleDecl.IsConcurrencyChecked = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this module has enable strict memory safety checking.
|
/// Whether this module has enabled strict memory safety checking.
|
||||||
bool strictMemorySafety() const {
|
bool strictMemorySafety() const {
|
||||||
return Bits.ModuleDecl.StrictMemorySafety;
|
return Bits.ModuleDecl.StrictMemorySafety;
|
||||||
}
|
}
|
||||||
@@ -827,6 +827,15 @@ public:
|
|||||||
Bits.ModuleDecl.StrictMemorySafety = value;
|
Bits.ModuleDecl.StrictMemorySafety = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether this module uses deferred code generation.
|
||||||
|
bool deferredCodeGen() const {
|
||||||
|
return Bits.ModuleDecl.DeferredCodeGen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDeferredCodeGen(bool value = true) {
|
||||||
|
Bits.ModuleDecl.DeferredCodeGen = value;
|
||||||
|
}
|
||||||
|
|
||||||
bool isObjCNameLookupCachePopulated() const {
|
bool isObjCNameLookupCachePopulated() const {
|
||||||
return Bits.ModuleDecl.ObjCNameLookupCachePopulated;
|
return Bits.ModuleDecl.ObjCNameLookupCachePopulated;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -324,6 +324,12 @@ EXPERIMENTAL_FEATURE(KeyPathWithMethodMembers, false)
|
|||||||
// Whether to enable @_used and @_section attributes
|
// Whether to enable @_used and @_section attributes
|
||||||
EXPERIMENTAL_FEATURE(SymbolLinkageMarkers, true)
|
EXPERIMENTAL_FEATURE(SymbolLinkageMarkers, true)
|
||||||
|
|
||||||
|
// Whether to emit an Embedded Swift module with "deferred" code generation,
|
||||||
|
// meaning that the only code that will be emitted into the object file is
|
||||||
|
// code that was marked as "never emit into client". For everything else,
|
||||||
|
// Swift still store the SIL and emit it into the client only when used.
|
||||||
|
EXPERIMENTAL_FEATURE(DeferredCodeGen, true)
|
||||||
|
|
||||||
// Whether to compile scripts lazily in immediate mode
|
// Whether to compile scripts lazily in immediate mode
|
||||||
EXPERIMENTAL_FEATURE(LazyImmediate, false)
|
EXPERIMENTAL_FEATURE(LazyImmediate, false)
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ class ExtendedValidationInfo {
|
|||||||
unsigned AllowNonResilientAccess: 1;
|
unsigned AllowNonResilientAccess: 1;
|
||||||
unsigned SerializePackageEnabled: 1;
|
unsigned SerializePackageEnabled: 1;
|
||||||
unsigned StrictMemorySafety: 1;
|
unsigned StrictMemorySafety: 1;
|
||||||
|
unsigned DeferredCodeGen: 1;
|
||||||
} Bits;
|
} Bits;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -251,7 +252,14 @@ public:
|
|||||||
void setStrictMemorySafety(bool val = true) {
|
void setStrictMemorySafety(bool val = true) {
|
||||||
Bits.StrictMemorySafety = val;
|
Bits.StrictMemorySafety = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool deferredCodeGen() const {
|
||||||
|
return Bits.DeferredCodeGen;
|
||||||
|
}
|
||||||
|
void setDeferredCodeGen(bool val = true) {
|
||||||
|
Bits.DeferredCodeGen = val;
|
||||||
|
}
|
||||||
|
|
||||||
bool hasCxxInteroperability() const { return Bits.HasCxxInteroperability; }
|
bool hasCxxInteroperability() const { return Bits.HasCxxInteroperability; }
|
||||||
void setHasCxxInteroperability(bool val) {
|
void setHasCxxInteroperability(bool val) {
|
||||||
Bits.HasCxxInteroperability = val;
|
Bits.HasCxxInteroperability = val;
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ UNINTERESTING_FEATURE(CodeItemMacros)
|
|||||||
UNINTERESTING_FEATURE(PreambleMacros)
|
UNINTERESTING_FEATURE(PreambleMacros)
|
||||||
UNINTERESTING_FEATURE(TupleConformances)
|
UNINTERESTING_FEATURE(TupleConformances)
|
||||||
UNINTERESTING_FEATURE(SymbolLinkageMarkers)
|
UNINTERESTING_FEATURE(SymbolLinkageMarkers)
|
||||||
|
UNINTERESTING_FEATURE(DeferredCodeGen)
|
||||||
UNINTERESTING_FEATURE(LazyImmediate)
|
UNINTERESTING_FEATURE(LazyImmediate)
|
||||||
UNINTERESTING_FEATURE(MoveOnlyClasses)
|
UNINTERESTING_FEATURE(MoveOnlyClasses)
|
||||||
UNINTERESTING_FEATURE(NoImplicitCopy)
|
UNINTERESTING_FEATURE(NoImplicitCopy)
|
||||||
|
|||||||
@@ -784,6 +784,7 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
|
|||||||
Bits.ModuleDecl.AllowNonResilientAccess = 0;
|
Bits.ModuleDecl.AllowNonResilientAccess = 0;
|
||||||
Bits.ModuleDecl.SerializePackageEnabled = 0;
|
Bits.ModuleDecl.SerializePackageEnabled = 0;
|
||||||
Bits.ModuleDecl.StrictMemorySafety = 0;
|
Bits.ModuleDecl.StrictMemorySafety = 0;
|
||||||
|
Bits.ModuleDecl.DeferredCodeGen = 0;
|
||||||
|
|
||||||
// Populate the module's files.
|
// Populate the module's files.
|
||||||
SmallVector<FileUnit *, 2> files;
|
SmallVector<FileUnit *, 2> files;
|
||||||
|
|||||||
@@ -1511,6 +1511,9 @@ ModuleDecl *CompilerInstance::getMainModule() const {
|
|||||||
MainModule->setSerializePackageEnabled();
|
MainModule->setSerializePackageEnabled();
|
||||||
if (Invocation.getLangOptions().hasFeature(Feature::StrictMemorySafety))
|
if (Invocation.getLangOptions().hasFeature(Feature::StrictMemorySafety))
|
||||||
MainModule->setStrictMemorySafety(true);
|
MainModule->setStrictMemorySafety(true);
|
||||||
|
if (Invocation.getLangOptions().hasFeature(Feature::Embedded) &&
|
||||||
|
Invocation.getLangOptions().hasFeature(Feature::DeferredCodeGen))
|
||||||
|
MainModule->setDeferredCodeGen(true);
|
||||||
|
|
||||||
configureAvailabilityDomains(getASTContext(),
|
configureAvailabilityDomains(getASTContext(),
|
||||||
Invocation.getFrontendOptions(), MainModule);
|
Invocation.getFrontendOptions(), MainModule);
|
||||||
|
|||||||
@@ -1112,10 +1112,20 @@ bool SILDeclRef::declHasNonUniqueDefinition(const ValueDecl *decl) {
|
|||||||
if (decl->isNeverEmittedIntoClient())
|
if (decl->isNeverEmittedIntoClient())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If the declaration is not from the main module, treat its definition as
|
/// @_alwaysEmitIntoClient means that we have a non-unique definition.
|
||||||
// non-unique.
|
if (decl->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>())
|
||||||
|
return true;
|
||||||
|
|
||||||
auto module = decl->getModuleContext();
|
auto module = decl->getModuleContext();
|
||||||
auto &ctx = module->getASTContext();
|
auto &ctx = module->getASTContext();
|
||||||
|
|
||||||
|
/// With deferred code generation, declarations are emitted as late as
|
||||||
|
/// possible, so they must have non-unique definitions.
|
||||||
|
if (module->deferredCodeGen())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If the declaration is not from the main module, treat its definition as
|
||||||
|
// non-unique.
|
||||||
return module != ctx.MainModule && ctx.MainModule;
|
return module != ctx.MainModule && ctx.MainModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -710,6 +710,9 @@ public:
|
|||||||
/// \c true if this module was built with strict memory safety.
|
/// \c true if this module was built with strict memory safety.
|
||||||
bool strictMemorySafety() const { return Core->strictMemorySafety(); }
|
bool strictMemorySafety() const { return Core->strictMemorySafety(); }
|
||||||
|
|
||||||
|
/// \c true if this module uses deferred code generation.
|
||||||
|
bool deferredCodeGen() const { return Core->deferredCodeGen(); }
|
||||||
|
|
||||||
/// Associates this module file with the AST node representing it.
|
/// Associates this module file with the AST node representing it.
|
||||||
///
|
///
|
||||||
/// Checks that the file is compatible with the AST module it's being loaded
|
/// Checks that the file is compatible with the AST module it's being loaded
|
||||||
|
|||||||
@@ -226,6 +226,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
|
|||||||
case options_block::STRICT_MEMORY_SAFETY:
|
case options_block::STRICT_MEMORY_SAFETY:
|
||||||
extendedInfo.setStrictMemorySafety(true);
|
extendedInfo.setStrictMemorySafety(true);
|
||||||
break;
|
break;
|
||||||
|
case options_block::DEFERRED_CODE_GEN:
|
||||||
|
extendedInfo.setDeferredCodeGen(true);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Unknown options record, possibly for use by a future version of the
|
// Unknown options record, possibly for use by a future version of the
|
||||||
// module format.
|
// module format.
|
||||||
@@ -1520,6 +1523,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
|
|||||||
Bits.AllowNonResilientAccess = extInfo.allowNonResilientAccess();
|
Bits.AllowNonResilientAccess = extInfo.allowNonResilientAccess();
|
||||||
Bits.SerializePackageEnabled = extInfo.serializePackageEnabled();
|
Bits.SerializePackageEnabled = extInfo.serializePackageEnabled();
|
||||||
Bits.StrictMemorySafety = extInfo.strictMemorySafety();
|
Bits.StrictMemorySafety = extInfo.strictMemorySafety();
|
||||||
|
Bits.DeferredCodeGen = extInfo.deferredCodeGen();
|
||||||
MiscVersion = info.miscVersion;
|
MiscVersion = info.miscVersion;
|
||||||
SDKVersion = info.sdkVersion;
|
SDKVersion = info.sdkVersion;
|
||||||
ModuleABIName = extInfo.getModuleABIName();
|
ModuleABIName = extInfo.getModuleABIName();
|
||||||
|
|||||||
@@ -421,8 +421,11 @@ private:
|
|||||||
/// Whether this module enabled strict memory safety.
|
/// Whether this module enabled strict memory safety.
|
||||||
unsigned StrictMemorySafety : 1;
|
unsigned StrictMemorySafety : 1;
|
||||||
|
|
||||||
|
/// Whether this module used deferred code generation.
|
||||||
|
unsigned DeferredCodeGen : 1;
|
||||||
|
|
||||||
// Explicitly pad out to the next word boundary.
|
// Explicitly pad out to the next word boundary.
|
||||||
unsigned : 2;
|
unsigned : 1;
|
||||||
} Bits = {};
|
} Bits = {};
|
||||||
static_assert(sizeof(ModuleBits) <= 8, "The bit set should be small");
|
static_assert(sizeof(ModuleBits) <= 8, "The bit set should be small");
|
||||||
|
|
||||||
@@ -696,6 +699,8 @@ public:
|
|||||||
|
|
||||||
bool strictMemorySafety() const { return Bits.StrictMemorySafety; }
|
bool strictMemorySafety() const { return Bits.StrictMemorySafety; }
|
||||||
|
|
||||||
|
bool deferredCodeGen() const { return Bits.DeferredCodeGen; }
|
||||||
|
|
||||||
/// How should \p dependency be loaded for a transitive import via \c this?
|
/// How should \p dependency be loaded for a transitive import via \c this?
|
||||||
///
|
///
|
||||||
/// If \p importNonPublicDependencies, more transitive dependencies
|
/// If \p importNonPublicDependencies, more transitive dependencies
|
||||||
|
|||||||
@@ -987,7 +987,8 @@ namespace options_block {
|
|||||||
CXX_STDLIB_KIND,
|
CXX_STDLIB_KIND,
|
||||||
PUBLIC_MODULE_NAME,
|
PUBLIC_MODULE_NAME,
|
||||||
SWIFT_INTERFACE_COMPILER_VERSION,
|
SWIFT_INTERFACE_COMPILER_VERSION,
|
||||||
STRICT_MEMORY_SAFETY
|
STRICT_MEMORY_SAFETY,
|
||||||
|
DEFERRED_CODE_GEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
using SDKPathLayout = BCRecordLayout<
|
using SDKPathLayout = BCRecordLayout<
|
||||||
@@ -1088,6 +1089,10 @@ namespace options_block {
|
|||||||
STRICT_MEMORY_SAFETY
|
STRICT_MEMORY_SAFETY
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
using DeferredCodeGenLayout = BCRecordLayout<
|
||||||
|
DEFERRED_CODE_GEN
|
||||||
|
>;
|
||||||
|
|
||||||
using PublicModuleNameLayout = BCRecordLayout<
|
using PublicModuleNameLayout = BCRecordLayout<
|
||||||
PUBLIC_MODULE_NAME,
|
PUBLIC_MODULE_NAME,
|
||||||
BCBlob
|
BCBlob
|
||||||
|
|||||||
@@ -864,6 +864,7 @@ void Serializer::writeBlockInfoBlock() {
|
|||||||
BLOCK_RECORD(options_block, ALLOW_NON_RESILIENT_ACCESS);
|
BLOCK_RECORD(options_block, ALLOW_NON_RESILIENT_ACCESS);
|
||||||
BLOCK_RECORD(options_block, SERIALIZE_PACKAGE_ENABLED);
|
BLOCK_RECORD(options_block, SERIALIZE_PACKAGE_ENABLED);
|
||||||
BLOCK_RECORD(options_block, STRICT_MEMORY_SAFETY);
|
BLOCK_RECORD(options_block, STRICT_MEMORY_SAFETY);
|
||||||
|
BLOCK_RECORD(options_block, DEFERRED_CODE_GEN);
|
||||||
BLOCK_RECORD(options_block, CXX_STDLIB_KIND);
|
BLOCK_RECORD(options_block, CXX_STDLIB_KIND);
|
||||||
BLOCK_RECORD(options_block, PUBLIC_MODULE_NAME);
|
BLOCK_RECORD(options_block, PUBLIC_MODULE_NAME);
|
||||||
BLOCK_RECORD(options_block, SWIFT_INTERFACE_COMPILER_VERSION);
|
BLOCK_RECORD(options_block, SWIFT_INTERFACE_COMPILER_VERSION);
|
||||||
@@ -1177,6 +1178,11 @@ void Serializer::writeHeader() {
|
|||||||
StrictMemorySafety.emit(ScratchRecord);
|
StrictMemorySafety.emit(ScratchRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (M->deferredCodeGen()) {
|
||||||
|
options_block::DeferredCodeGenLayout DeferredCodeGen(Out);
|
||||||
|
DeferredCodeGen.emit(ScratchRecord);
|
||||||
|
}
|
||||||
|
|
||||||
if (M->hasCxxInteroperability()) {
|
if (M->hasCxxInteroperability()) {
|
||||||
options_block::HasCxxInteroperabilityEnabledLayout
|
options_block::HasCxxInteroperabilityEnabledLayout
|
||||||
CxxInteroperabilityEnabled(Out);
|
CxxInteroperabilityEnabled(Out);
|
||||||
|
|||||||
@@ -976,6 +976,8 @@ LoadedFile *SerializedModuleLoaderBase::loadAST(
|
|||||||
M.setIsConcurrencyChecked();
|
M.setIsConcurrencyChecked();
|
||||||
if (loadedModuleFile->strictMemorySafety())
|
if (loadedModuleFile->strictMemorySafety())
|
||||||
M.setStrictMemorySafety();
|
M.setStrictMemorySafety();
|
||||||
|
if (loadedModuleFile->deferredCodeGen())
|
||||||
|
M.setDeferredCodeGen();
|
||||||
if (loadedModuleFile->hasCxxInteroperability()) {
|
if (loadedModuleFile->hasCxxInteroperability()) {
|
||||||
M.setHasCxxInteroperability();
|
M.setHasCxxInteroperability();
|
||||||
M.setCXXStdlibKind(loadedModuleFile->getCXXStdlibKind());
|
M.setCXXStdlibKind(loadedModuleFile->getCXXStdlibKind());
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
// RUN: %target-run %t/Application | %FileCheck %s
|
// RUN: %target-run %t/Application | %FileCheck %s
|
||||||
|
|
||||||
// Test #2: Root is an "intermediate" library for everything
|
// Test #2: Root is an "intermediate" library for everything
|
||||||
// RUN: %target-swift-frontend -c -emit-module -o %t/Root.o %t/Root.swift -enable-experimental-feature Embedded -emit-empty-object-file -parse-as-library
|
// RUN: %target-swift-frontend -c -emit-module -o %t/Root.o %t/Root.swift -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientA.o %t/ClientA.swift -enable-experimental-feature Embedded -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientA.o %t/ClientA.swift -enable-experimental-feature Embedded -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientB.o %t/ClientB.swift -enable-experimental-feature Embedded -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientB.o %t/ClientB.swift -enable-experimental-feature Embedded -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/Application.o %t/Application.swift -enable-experimental-feature Embedded -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/Application.o %t/Application.swift -enable-experimental-feature Embedded -parse-as-library
|
||||||
@@ -41,26 +41,26 @@
|
|||||||
|
|
||||||
// Test #3: ClientA as an "intermediate" library
|
// Test #3: ClientA as an "intermediate" library
|
||||||
// RUN: %target-swift-frontend -c -emit-module -o %t/Root.o %t/Root.swift -enable-experimental-feature Embedded -parse-as-library
|
// RUN: %target-swift-frontend -c -emit-module -o %t/Root.o %t/Root.swift -enable-experimental-feature Embedded -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientA.o %t/ClientA.swift -enable-experimental-feature Embedded -emit-empty-object-file -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientA.o %t/ClientA.swift -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientB.o %t/ClientB.swift -enable-experimental-feature Embedded -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientB.o %t/ClientB.swift -enable-experimental-feature Embedded -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/Application.o %t/Application.swift -enable-experimental-feature Embedded -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/Application.o %t/Application.swift -enable-experimental-feature Embedded -parse-as-library
|
||||||
// RUN: %target-clang %target-clang-resource-dir-opt %t/Root.o %t/ClientA.o %t/ClientB.o %t/Application.o -o %t/Application
|
// RUN: %target-clang %target-clang-resource-dir-opt %t/Root.o %t/ClientA.o %t/ClientB.o %t/Application.o -o %t/Application
|
||||||
// RUN: %target-run %t/Application | %FileCheck %s
|
// RUN: %target-run %t/Application | %FileCheck %s
|
||||||
|
|
||||||
// Test #4: Root and ClientA as "intermediate" libraries
|
// Test #4: Root and ClientA as "intermediate" libraries
|
||||||
// RUN: %target-swift-frontend -c -emit-module -o %t/Root.o %t/Root.swift -enable-experimental-feature Embedded -emit-empty-object-file -parse-as-library
|
// RUN: %target-swift-frontend -c -emit-module -o %t/Root.o %t/Root.swift -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientA.o %t/ClientA.swift -enable-experimental-feature Embedded -emit-empty-object-file -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientA.o %t/ClientA.swift -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientB.o %t/ClientB.swift -enable-experimental-feature Embedded -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientB.o %t/ClientB.swift -enable-experimental-feature Embedded -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/Application.o %t/Application.swift -enable-experimental-feature Embedded -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/Application.o %t/Application.swift -enable-experimental-feature Embedded -parse-as-library
|
||||||
// RUN: %target-clang %target-clang-resource-dir-opt %t/Root.o %t/ClientA.o %t/ClientB.o %t/Application.o -o %t/Application
|
// RUN: %target-clang %target-clang-resource-dir-opt %t/Root.o %t/ClientA.o %t/ClientB.o %t/Application.o -o %t/Application
|
||||||
// RUN: %target-run %t/Application | %FileCheck %s
|
// RUN: %target-run %t/Application | %FileCheck %s
|
||||||
|
|
||||||
// Test #%: All "intermediate", all the time. Main drives code generation
|
// Test #%: All "intermediate", all the time. Main drives code generation
|
||||||
// TODO: This requires -emit-empty-object-file to still emit the main symbol.
|
// TODO: @main needs to drive the generation of code here.
|
||||||
// RUN: %target-swift-frontend -c -emit-module -o %t/Root.o %t/Root.swift -enable-experimental-feature Embedded -emit-empty-object-file -parse-as-library
|
// RUN: %target-swift-frontend -c -emit-module -o %t/Root.o %t/Root.swift -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientA.o %t/ClientA.swift -enable-experimental-feature Embedded -emit-empty-object-file -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientA.o %t/ClientA.swift -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientB.o %t/ClientB.swift -enable-experimental-feature Embedded -emit-empty-object-file -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/ClientB.o %t/ClientB.swift -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -parse-as-library
|
||||||
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/Application.o %t/Application.swift -enable-experimental-feature Embedded -emit-empty-object-file -parse-as-library
|
// RUN: %target-swift-frontend -c -I %t -emit-module -o %t/Application.o %t/Application.swift -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -parse-as-library
|
||||||
// RUN-TODO: %target-clang %target-clang-resource-dir-opt %t/Root.o %t/ClientA.o %t/ClientB.o %t/Application.o -o %t/Application
|
// RUN-TODO: %target-clang %target-clang-resource-dir-opt %t/Root.o %t/ClientA.o %t/ClientB.o %t/Application.o -o %t/Application
|
||||||
// RUN-TODO: %target-run %t/Application | %FileCheck %s
|
// RUN-TODO: %target-run %t/Application | %FileCheck %s
|
||||||
|
|
||||||
@@ -68,6 +68,7 @@
|
|||||||
// REQUIRES: swift_in_compiler
|
// REQUIRES: swift_in_compiler
|
||||||
// REQUIRES: executable_test
|
// REQUIRES: executable_test
|
||||||
// REQUIRES: swift_feature_Embedded
|
// REQUIRES: swift_feature_Embedded
|
||||||
|
// REQUIRES: swift_feature_DeferredCodeGen
|
||||||
|
|
||||||
//--- Root.swift
|
//--- Root.swift
|
||||||
struct Point {
|
struct Point {
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
// Library module
|
// Library module
|
||||||
|
|
||||||
// SIL checking
|
// SIL checking
|
||||||
// RUN: %target-swift-frontend %t/Library.swift -parse-as-library -entry-point-function-name Library_main -enable-experimental-feature Embedded -emit-empty-object-file -emit-sil -emit-module-path %t/Modules/Library.swiftmodule -o - | %FileCheck -check-prefix LIBRARY-SIL %s
|
// RUN: %target-swift-frontend %t/Library.swift -parse-as-library -entry-point-function-name Library_main -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -emit-sil -emit-module-path %t/Modules/Library.swiftmodule -o - | %FileCheck -check-prefix LIBRARY-SIL %s
|
||||||
|
|
||||||
// IR checking to ensure we get the right weak symbols.
|
// IR checking to ensure we get the right weak symbols.
|
||||||
// RUN: %target-swift-frontend %t/Library.swift -parse-as-library -entry-point-function-name Library_main -enable-experimental-feature Embedded -emit-empty-object-file -emit-ir -o - | %FileCheck -check-prefix LIBRARY-IR --dump-input-filter all %s
|
// RUN: %target-swift-frontend %t/Library.swift -parse-as-library -entry-point-function-name Library_main -enable-experimental-feature Embedded -enable-experimental-feature DeferredCodeGen -emit-ir -o - | %FileCheck -check-prefix LIBRARY-IR --dump-input-filter all %s
|
||||||
|
|
||||||
// Application module
|
// Application module
|
||||||
|
|
||||||
@@ -17,12 +17,14 @@
|
|||||||
|
|
||||||
// REQUIRES: swift_in_compiler
|
// REQUIRES: swift_in_compiler
|
||||||
// REQUIRES: swift_feature_Embedded
|
// REQUIRES: swift_feature_Embedded
|
||||||
|
// REQUIRES: swift_feature_DeferredCodeGen
|
||||||
|
|
||||||
//--- Library.swift
|
//--- Library.swift
|
||||||
|
|
||||||
// TODO: These are expected once "emit empty object file" becomes "be lazy".
|
// TODO: Once global variables can be emitted lazily, these should be -NOT
|
||||||
// LIBRARY-IR-NOT: @"$es23_swiftEmptyArrayStorageSi_S3itvp" = linkonce_odr {{(protected |dllexport )?}}global
|
// again, then show up in the application binary if we use them.
|
||||||
// LIBRARY-IR-NOT: @"$es16_emptyBoxStorageSi_Sitvp" = linkonce_odr {{(protected |dllexport )?}}global
|
// LIBRARY-IR: @"$es23_swiftEmptyArrayStorageSi_S3itvp" = weak_odr {{(protected |dllexport )?}}global
|
||||||
|
// LIBRARY-IR: @"$es16_emptyBoxStorageSi_Sitvp" = weak_odr {{(protected |dllexport )?}}global
|
||||||
|
|
||||||
// LIBRARY-IR-NOT: define {{.*}}@"$e7Library5helloSaySiGyF"()
|
// LIBRARY-IR-NOT: define {{.*}}@"$e7Library5helloSaySiGyF"()
|
||||||
public func hello() -> [Int] {
|
public func hello() -> [Int] {
|
||||||
@@ -47,13 +49,17 @@ private func throughPrivate() -> [Int] {
|
|||||||
// LIBRARY-IR-NOT: unnecessary
|
// LIBRARY-IR-NOT: unnecessary
|
||||||
public func unnecessary() -> Int64 { 5 }
|
public func unnecessary() -> Int64 { 5 }
|
||||||
|
|
||||||
|
// LIBRARY-IR: define {{.*}} @"$e7Library14unusedYetThere
|
||||||
|
@_neverEmitIntoClient
|
||||||
|
public func unusedYetThere() -> Int64 { 5 }
|
||||||
|
|
||||||
// LIBRARY-IR-NOT: define swiftcc
|
// LIBRARY-IR-NOT: define swiftcc
|
||||||
// LIBRARY-IR-NOT: define hidden swiftcc
|
// LIBRARY-IR-NOT: define hidden swiftcc
|
||||||
|
|
||||||
// LIBRARY-IR-NOT: define {{.*}} @"$es27_allocateUninitializedArrayySayxG_BptBwlFSi_Tg5"
|
// LIBRARY-IR-NOT: define {{.*}} @"$es27_allocateUninitializedArrayySayxG_BptBwlFSi_Tg5"
|
||||||
|
|
||||||
// LIBRARY-SIL: sil [ossa] @$e7Library5helloSaySiGyF
|
// LIBRARY-SIL: sil @$e7Library5helloSaySiGyF
|
||||||
// LIBRARY-SIL: sil [ossa] @$e7Library8getArraySaySiGyF : $@convention(thin) () -> @owned Array<Int> {
|
// LIBRARY-SIL: sil @$e7Library8getArraySaySiGyF : $@convention(thin) () -> @owned Array<Int> {
|
||||||
|
|
||||||
//--- Application.swift
|
//--- Application.swift
|
||||||
import Library
|
import Library
|
||||||
|
|||||||
Reference in New Issue
Block a user