Skip to content

Commit 02f6aff

Browse files
Merge pull request #4665 from swiftwasm/main
[pull] swiftwasm from main
2 parents 6c02aa9 + 797d94d commit 02f6aff

24 files changed

+235
-47
lines changed

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,10 @@ class ASTContext final {
880880
/// for extended existential types.
881881
AvailabilityContext getParameterizedExistentialRuntimeAvailability();
882882

883+
/// Get the runtime availability of immortal ref-count symbols, which are
884+
/// needed to place array buffers into constant data sections.
885+
AvailabilityContext getImmortalRefCountSymbolsAvailability();
886+
883887
/// Get the runtime availability of features introduced in the Swift 5.2
884888
/// compiler for the target platform.
885889
AvailabilityContext getSwift52Availability();

include/swift/AST/IRGenOptions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ class IRGenOptions {
402402
/// and protocol conformance caches.
403403
unsigned NoPreallocatedInstantiationCaches : 1;
404404

405+
unsigned DisableReadonlyStaticObjects : 1;
406+
405407
/// The number of threads for multi-threaded code generation.
406408
unsigned NumThreads = 0;
407409

@@ -470,7 +472,8 @@ class IRGenOptions {
470472
EnableGlobalISel(false), VirtualFunctionElimination(false),
471473
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
472474
InternalizeAtLink(false), InternalizeSymbols(false),
473-
NoPreallocatedInstantiationCaches(false), CmdArgs(),
475+
NoPreallocatedInstantiationCaches(false),
476+
DisableReadonlyStaticObjects(false), CmdArgs(),
474477
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
475478
TypeInfoFilter(TypeInfoDumpFilter::All) {
476479
#ifndef NDEBUG

include/swift/IRGen/Linking.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,9 @@ class LinkEntity {
364364
/// A SIL global variable. The pointer is a SILGlobalVariable*.
365365
SILGlobalVariable,
366366

367+
/// An outlined read-only global object. The pointer is a SILGlobalVariable*.
368+
ReadOnlyGlobalObject,
369+
367370
// These next few are protocol-conformance kinds.
368371

369372
/// A direct protocol witness table. The secondary pointer is a
@@ -993,13 +996,7 @@ class LinkEntity {
993996
return entity;
994997
}
995998

996-
static LinkEntity forSILGlobalVariable(SILGlobalVariable *G) {
997-
LinkEntity entity;
998-
entity.Pointer = G;
999-
entity.SecondaryPointer = nullptr;
1000-
entity.Data = LINKENTITY_SET_FIELD(Kind, unsigned(Kind::SILGlobalVariable));
1001-
return entity;
1002-
}
999+
static LinkEntity forSILGlobalVariable(SILGlobalVariable *G, IRGenModule &IGM);
10031000

10041001
static LinkEntity
10051002
forDifferentiabilityWitness(const SILDifferentiabilityWitness *witness) {
@@ -1420,7 +1417,8 @@ class LinkEntity {
14201417
}
14211418

14221419
SILGlobalVariable *getSILGlobalVariable() const {
1423-
assert(getKind() == Kind::SILGlobalVariable);
1420+
assert(getKind() == Kind::SILGlobalVariable ||
1421+
getKind() == Kind::ReadOnlyGlobalObject);
14241422
return reinterpret_cast<SILGlobalVariable*>(Pointer);
14251423
}
14261424

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,10 @@ def disable_preallocated_instantiation_caches : Flag<["-"], "disable-preallocate
641641
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
642642
HelpText<"Avoid preallocating metadata instantiation caches in globals">;
643643

644+
def disable_readonly_static_objects : Flag<["-"], "disable-readonly-static-objects">,
645+
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
646+
HelpText<"Avoid allocating static objects in a read-only data section">;
647+
644648
def trap_function
645649
: Separate<["-"], "trap-function">, MetaVarName<"<name>">,
646650
HelpText<"Lower traps to calls to this function instead of trap instructions">;

lib/AST/Availability.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,13 @@ ASTContext::getParameterizedExistentialRuntimeAvailability() {
399399
return getSwift57Availability();
400400
}
401401

402+
AvailabilityContext
403+
ASTContext::getImmortalRefCountSymbolsAvailability() {
404+
// TODO: replace this with a concrete swift version once we have it.
405+
// rdar://94185998
406+
return getSwiftFutureAvailability();
407+
}
408+
402409
AvailabilityContext ASTContext::getSwift52Availability() {
403410
auto target = LangOpts.Target;
404411

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,6 +2329,10 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
23292329
Opts.NoPreallocatedInstantiationCaches = true;
23302330
}
23312331

2332+
if (Args.hasArg(OPT_disable_readonly_static_objects)) {
2333+
Opts.DisableReadonlyStaticObjects = true;
2334+
}
2335+
23322336
// Default to disabling swift async extended frame info on anything but
23332337
// darwin. Other platforms are unlikely to have support for extended frame
23342338
// pointer information.

lib/IRGen/GenConstant.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,27 @@ llvm::Constant *irgen::emitConstantObject(IRGenModule &IGM, ObjectInst *OI,
278278
}
279279
}
280280
// Construct the object header.
281-
llvm::Type *ObjectHeaderTy = sTy->getElementType(0);
282-
assert(ObjectHeaderTy->isStructTy());
283-
elts[0] = llvm::Constant::getNullValue(ObjectHeaderTy);
281+
llvm::StructType *ObjectHeaderTy = cast<llvm::StructType>(sTy->getElementType(0));
282+
283+
if (IGM.canMakeStaticObjectsReadOnly()) {
284+
if (!IGM.swiftImmortalRefCount) {
285+
auto *var = new llvm::GlobalVariable(IGM.Module, IGM.Int8Ty,
286+
/*constant*/ true, llvm::GlobalValue::ExternalLinkage,
287+
/*initializer*/ nullptr, "_swiftImmortalRefCount");
288+
IGM.swiftImmortalRefCount = var;
289+
}
290+
if (!IGM.swiftStaticArrayMetadata) {
291+
auto *var = new llvm::GlobalVariable(IGM.Module, IGM.TypeMetadataStructTy,
292+
/*constant*/ true, llvm::GlobalValue::ExternalLinkage,
293+
/*initializer*/ nullptr, "_swiftStaticArrayMetadata");
294+
IGM.swiftStaticArrayMetadata = var;
295+
}
296+
elts[0] = llvm::ConstantStruct::get(ObjectHeaderTy, {
297+
IGM.swiftStaticArrayMetadata,
298+
llvm::ConstantExpr::getPtrToInt(IGM.swiftImmortalRefCount, IGM.IntPtrTy)});
299+
} else {
300+
elts[0] = llvm::Constant::getNullValue(ObjectHeaderTy);
301+
}
284302
insertPadding(elts, sTy);
285303
return llvm::ConstantStruct::get(sTy, elts);
286304
}

lib/IRGen/GenDecl.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,7 +2482,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
24822482
return Address(addr, alignment);
24832483
}
24842484

2485-
LinkEntity entity = LinkEntity::forSILGlobalVariable(var);
2485+
LinkEntity entity = LinkEntity::forSILGlobalVariable(var, *this);
24862486
ResilienceExpansion expansion = getResilienceExpansionForLayout(var);
24872487

24882488
llvm::Type *storageType;
@@ -2528,28 +2528,33 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
25282528

25292529
// Check whether we've created the global variable already.
25302530
// FIXME: We should integrate this into the LinkEntity cache more cleanly.
2531-
auto gvar = Module.getGlobalVariable(var->getName(), /*allowInternal*/ true);
2531+
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
2532+
auto gvar = Module.getGlobalVariable(link.getName(), /*allowInternal*/ true);
25322533
if (gvar) {
25332534
if (forDefinition)
25342535
updateLinkageForDefinition(*this, gvar, entity);
25352536
} else {
2536-
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
25372537
llvm::Type *storageTypeWithContainer = storageType;
25382538
if (var->isInitializedObject()) {
2539-
// A statically initialized object must be placed into a container struct
2540-
// because the swift_initStaticObject needs a swift_once_t at offset -1:
2541-
// struct Container {
2542-
// swift_once_t token[fixedAlignment / sizeof(swift_once_t)];
2543-
// HeapObject object;
2544-
// };
2545-
std::string typeName = storageType->getStructName().str() + 'c';
2546-
assert(fixedAlignment >= getPointerAlignment());
2547-
unsigned numTokens = fixedAlignment.getValue() /
2548-
getPointerAlignment().getValue();
2549-
storageTypeWithContainer = llvm::StructType::create(getLLVMContext(),
2550-
{llvm::ArrayType::get(OnceTy, numTokens), storageType}, typeName);
2551-
gvar = createVariable(*this, link, storageTypeWithContainer,
2552-
fixedAlignment);
2539+
if (canMakeStaticObjectsReadOnly()) {
2540+
gvar = createVariable(*this, link, storageType, fixedAlignment);
2541+
gvar->setConstant(true);
2542+
} else {
2543+
// A statically initialized object must be placed into a container struct
2544+
// because the swift_initStaticObject needs a swift_once_t at offset -1:
2545+
// struct Container {
2546+
// swift_once_t token[fixedAlignment / sizeof(swift_once_t)];
2547+
// HeapObject object;
2548+
// };
2549+
std::string typeName = storageType->getStructName().str() + 'c';
2550+
assert(fixedAlignment >= getPointerAlignment());
2551+
unsigned numTokens = fixedAlignment.getValue() /
2552+
getPointerAlignment().getValue();
2553+
storageTypeWithContainer = llvm::StructType::create(getLLVMContext(),
2554+
{llvm::ArrayType::get(OnceTy, numTokens), storageType}, typeName);
2555+
gvar = createVariable(*this, link, storageTypeWithContainer,
2556+
fixedAlignment);
2557+
}
25532558
} else {
25542559
StringRef name;
25552560
Optional<SILLocation> loc;
@@ -2574,7 +2579,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
25742579
gvar->setComdat(nullptr);
25752580
}
25762581
llvm::Constant *addr = gvar;
2577-
if (var->isInitializedObject()) {
2582+
if (var->isInitializedObject() && !canMakeStaticObjectsReadOnly()) {
25782583
// Project out the object from the container.
25792584
llvm::Constant *Indices[2] = {
25802585
llvm::ConstantExpr::getIntegerValue(Int32Ty, APInt(32, 0)),

lib/IRGen/IRGenModule.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,19 @@ bool IRGenModule::shouldPrespecializeGenericMetadata() {
17851785
canPrespecializeTarget;
17861786
}
17871787

1788+
bool IRGenModule::canMakeStaticObjectsReadOnly() {
1789+
if (getOptions().DisableReadonlyStaticObjects)
1790+
return false;
1791+
1792+
// TODO: Support constant static arrays on other platforms, too.
1793+
// See also the comment in GlobalObjects.cpp.
1794+
if (!Triple.isOSDarwin())
1795+
return false;
1796+
1797+
return getAvailabilityContext().isContainedIn(
1798+
Context.getImmortalRefCountSymbolsAvailability());
1799+
}
1800+
17881801
void IRGenerator::addGenModule(SourceFile *SF, IRGenModule *IGM) {
17891802
assert(GenModules.count(SF) == 0);
17901803
GenModules[SF] = IGM;

lib/IRGen/IRGenModule.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,9 @@ class IRGenModule {
763763

764764
llvm::GlobalVariable *TheTrivialPropertyDescriptor = nullptr;
765765

766+
llvm::GlobalVariable *swiftImmortalRefCount = nullptr;
767+
llvm::GlobalVariable *swiftStaticArrayMetadata = nullptr;
768+
766769
/// Used to create unique names for class layout types with tail allocated
767770
/// elements.
768771
unsigned TailElemTypeID = 0;
@@ -886,6 +889,8 @@ class IRGenModule {
886889

887890
bool shouldPrespecializeGenericMetadata();
888891

892+
bool canMakeStaticObjectsReadOnly();
893+
889894
Size getAtomicBoolSize() const { return AtomicBoolSize; }
890895
Alignment getAtomicBoolAlignment() const { return AtomicBoolAlign; }
891896

lib/IRGen/IRGenSIL.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,7 +2765,7 @@ void IRGenSILFunction::visitGlobalValueInst(GlobalValueInst *i) {
27652765
NotForDefinition).getAddress();
27662766
// We don't need to initialize the global object if it's never used for
27672767
// something which can access the object header.
2768-
if (!hasOnlyProjections(i)) {
2768+
if (!hasOnlyProjections(i) && !IGM.canMakeStaticObjectsReadOnly()) {
27692769
auto ClassType = loweredTy.getASTType();
27702770
llvm::Value *Metadata =
27712771
emitClassHeapMetadataRef(*this, ClassType, MetadataValueType::TypeMetadata,
@@ -7099,8 +7099,11 @@ void IRGenModule::emitSILStaticInitializers() {
70997099
"cannot emit a static initializer for dynamically-sized global");
71007100
#endif
71017101

7102+
LinkEntity entity = LinkEntity::forSILGlobalVariable(&Global, *this);
7103+
std::string name = entity.mangleAsString();
7104+
71027105
auto *IRGlobal =
7103-
Module.getGlobalVariable(Global.getName(), true /* = AllowLocal */);
7106+
Module.getGlobalVariable(name, true /* = AllowLocal */);
71047107

71057108
// A check for multi-threaded compilation: Is this the llvm module where the
71067109
// global is defined and not only referenced (or not referenced at all).
@@ -7110,10 +7113,14 @@ void IRGenModule::emitSILStaticInitializers() {
71107113
if (auto *OI = dyn_cast<ObjectInst>(InitValue)) {
71117114
StructLayout *Layout = StaticObjectLayouts[&Global].get();
71127115
llvm::Constant *InitVal = emitConstantObject(*this, OI, Layout);
7113-
auto *ContainerTy = cast<llvm::StructType>(IRGlobal->getValueType());
7114-
auto *zero = llvm::ConstantAggregateZero::get(ContainerTy->getElementType(0));
7115-
IRGlobal->setInitializer(llvm::ConstantStruct::get(ContainerTy,
7116-
{zero , InitVal}));
7116+
if (canMakeStaticObjectsReadOnly()) {
7117+
IRGlobal->setInitializer(InitVal);
7118+
} else {
7119+
auto *ContainerTy = cast<llvm::StructType>(IRGlobal->getValueType());
7120+
auto *zero = llvm::ConstantAggregateZero::get(ContainerTy->getElementType(0));
7121+
IRGlobal->setInitializer(llvm::ConstantStruct::get(ContainerTy,
7122+
{zero , InitVal}));
7123+
}
71177124
continue;
71187125
}
71197126

lib/IRGen/Linking.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@ UniversalLinkageInfo::UniversalLinkageInfo(const llvm::Triple &triple,
9191
UseDLLStorage(useDllStorage(triple)), Internalize(isStaticLibrary),
9292
HasMultipleIGMs(hasMultipleIGMs), ForcePublicDecls(forcePublicDecls) {}
9393

94+
LinkEntity LinkEntity::forSILGlobalVariable(SILGlobalVariable *G,
95+
IRGenModule &IGM) {
96+
LinkEntity entity;
97+
entity.Pointer = G;
98+
entity.SecondaryPointer = nullptr;
99+
auto kind = (G->isInitializedObject() && IGM.canMakeStaticObjectsReadOnly() ?
100+
Kind::ReadOnlyGlobalObject : Kind::SILGlobalVariable);
101+
entity.Data = unsigned(kind) << KindShift;
102+
return entity;
103+
}
104+
105+
94106
/// Mangle this entity into the given buffer.
95107
void LinkEntity::mangle(SmallVectorImpl<char> &buffer) const {
96108
llvm::raw_svector_ostream stream(buffer);
@@ -454,6 +466,9 @@ std::string LinkEntity::mangleAsString() const {
454466
case Kind::SILGlobalVariable:
455467
return getSILGlobalVariable()->getName().str();
456468

469+
case Kind::ReadOnlyGlobalObject:
470+
return getSILGlobalVariable()->getName().str() + "r";
471+
457472
case Kind::ReflectionBuiltinDescriptor:
458473
return mangler.mangleReflectionBuiltinDescriptor(getType());
459474
case Kind::ReflectionFieldDescriptor:
@@ -787,6 +802,7 @@ SILLinkage LinkEntity::getLinkage(ForDefinition_t forDefinition) const {
787802
return getSILLinkage(getDeclLinkage(getDecl()), forDefinition);
788803

789804
case Kind::SILGlobalVariable:
805+
case Kind::ReadOnlyGlobalObject:
790806
return getSILGlobalVariable()->getLinkage();
791807

792808
case Kind::ReflectionBuiltinDescriptor:
@@ -882,6 +898,7 @@ bool LinkEntity::isContextDescriptor() const {
882898
case Kind::DefaultAssociatedConformanceAccessor:
883899
case Kind::SILFunction:
884900
case Kind::SILGlobalVariable:
901+
case Kind::ReadOnlyGlobalObject:
885902
case Kind::ProtocolWitnessTable:
886903
case Kind::ProtocolWitnessTablePattern:
887904
case Kind::GenericProtocolWitnessTableInstantiationFunction:
@@ -1129,6 +1146,7 @@ Alignment LinkEntity::getAlignment(IRGenModule &IGM) const {
11291146
bool LinkEntity::isWeakImported(ModuleDecl *module) const {
11301147
switch (getKind()) {
11311148
case Kind::SILGlobalVariable:
1149+
case Kind::ReadOnlyGlobalObject:
11321150
if (getSILGlobalVariable()->getDecl()) {
11331151
return getSILGlobalVariable()->getDecl()->isWeakImported(module);
11341152
}
@@ -1317,6 +1335,7 @@ DeclContext *LinkEntity::getDeclContextForEmission() const {
13171335
return getSILFunction()->getDeclContext();
13181336

13191337
case Kind::SILGlobalVariable:
1338+
case Kind::ReadOnlyGlobalObject:
13201339
if (auto decl = getSILGlobalVariable()->getDecl())
13211340
return decl->getDeclContext();
13221341

test/Distributed/Runtime/distributed_actor_in_other_module.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
// FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574
1515
// UNSUPPORTED: OS=windows-msvc
1616

17-
// REQUIRES: rdar92277324
18-
1917
import Distributed
2018
import EchoActorModule
2119
import FakeDistributedActorSystems

test/Interop/SwiftToCxx/initializers/init-in-cxx-execution.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// REQUIRES: executable_test
1212

13+
// UNSUPPORTED: CPU=arm64e
14+
1315
#include <assert.h>
1416
#include "inits.h"
1517

test/Interop/SwiftToCxx/methods/method-in-cxx-execution.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// REQUIRES: executable_test
1212

13+
// UNSUPPORTED: CPU=arm64e
14+
1315
#include <assert.h>
1416
#include "methods.h"
1517

test/Interop/SwiftToCxx/methods/mutating-method-in-cxx-execution.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// REQUIRES: executable_test
1212

13+
// UNSUPPORTED: CPU=arm64e
14+
1315
#include <assert.h>
1416
#include "methods.h"
1517

test/Interop/SwiftToCxx/properties/getter-in-cxx-execution.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// REQUIRES: executable_test
1212

13+
// UNSUPPORTED: CPU=arm64e
14+
1315
#include <assert.h>
1416
#include "properties.h"
1517

test/Interop/SwiftToCxx/structs/large-structs-pass-return-indirect-in-cxx-execution.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// REQUIRES: executable_test
1212

13+
// UNSUPPORTED: CPU=arm64e
14+
1315
#include <assert.h>
1416
#include "structs.h"
1517

0 commit comments

Comments
 (0)