Skip to content

Commit 488d531

Browse files
committed
Enhance -assume-single-threaded option (SR-3945)
1 parent a99141c commit 488d531

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+420
-205
lines changed

include/swift/AST/SILOptions.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/ADT/StringRef.h"
2222
#include <string>
2323
#include <climits>
24+
#include <cstdlib>
2425

2526
namespace swift {
2627

@@ -121,7 +122,9 @@ class SILOptions {
121122
bool AssumeUnqualifiedOwnershipWhenParsing = false;
122123

123124
/// Assume that code will be executed in a single-threaded environment.
124-
bool AssumeSingleThreaded = false;
125+
/// TODO: return to false when we pass "-Xfrontend -assume-single-threaded"
126+
/// to swift compiler while building standard library.
127+
bool AssumeSingleThreaded = std::getenv("SWIFT_ASSUME_SINGLE_THREADED");
125128
};
126129

127130
} // end namespace swift

include/swift/Runtime/HeapObject.h

+23
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,16 @@ SWIFT_RT_ENTRY_VISIBILITY
510510
void swift_unownedRelease(HeapObject *value)
511511
SWIFT_CC(RegisterPreservingCC);
512512

513+
/// Increment the unowned retain count.
514+
SWIFT_RT_ENTRY_VISIBILITY
515+
void swift_nonatomic_unownedRetain(HeapObject *value)
516+
SWIFT_CC(RegisterPreservingCC);
517+
518+
/// Decrement the unowned retain count.
519+
SWIFT_RT_ENTRY_VISIBILITY
520+
void swift_nonatomic_unownedRelease(HeapObject *value)
521+
SWIFT_CC(RegisterPreservingCC);
522+
513523
/// Increment the unowned retain count by n.
514524
SWIFT_RT_ENTRY_VISIBILITY
515525
void swift_unownedRetain_n(HeapObject *value, int n)
@@ -526,13 +536,26 @@ SWIFT_RT_ENTRY_VISIBILITY
526536
void swift_unownedRetainStrong(HeapObject *value)
527537
SWIFT_CC(RegisterPreservingCC);
528538

539+
/// Increment the strong retain count of an object, aborting if it has
540+
/// been deallocated.
541+
SWIFT_RT_ENTRY_VISIBILITY
542+
void swift_nonatomic_unownedRetainStrong(HeapObject *value)
543+
SWIFT_CC(RegisterPreservingCC);
544+
529545
/// Increment the strong retain count of an object which may have been
530546
/// deallocated, aborting if it has been deallocated, and decrement its
531547
/// unowned reference count.
532548
SWIFT_RT_ENTRY_VISIBILITY
533549
void swift_unownedRetainStrongAndRelease(HeapObject *value)
534550
SWIFT_CC(RegisterPreservingCC);
535551

552+
/// Increment the strong retain count of an object which may have been
553+
/// deallocated, aborting if it has been deallocated, and decrement its
554+
/// weak/unowned reference count.
555+
SWIFT_RT_ENTRY_VISIBILITY
556+
void swift_nonatomic_unownedRetainStrongAndRelease(HeapObject *value)
557+
SWIFT_CC(RegisterPreservingCC);
558+
536559
/// Aborts if the object has been deallocated.
537560
SWIFT_RUNTIME_EXPORT
538561
void swift_unownedCheck(HeapObject *value);

include/swift/Runtime/RuntimeFunctions.def

+28
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,20 @@ FUNCTION(NativeUnownedRelease, swift_unownedRelease, RegisterPreservingCC,
369369
ARGS(RefCountedPtrTy),
370370
ATTRS(NoUnwind))
371371

372+
// void swift_nonatomic_unownedRetain(void *ptr);
373+
FUNCTION(NonAtomicNativeUnownedRetain, swift_nonatomic_unownedRetain,
374+
RegisterPreservingCC,
375+
RETURNS(VoidTy),
376+
ARGS(RefCountedPtrTy),
377+
ATTRS(NoUnwind))
378+
379+
// void swift_nonatomic_unownedRelease(void *ptr);
380+
FUNCTION(NonAtomicNativeUnownedRelease, swift_nonatomic_unownedRelease,
381+
RegisterPreservingCC,
382+
RETURNS(VoidTy),
383+
ARGS(RefCountedPtrTy),
384+
ATTRS(NoUnwind))
385+
372386
// void swift_unownedRetain_n(void *ptr, int32_t n);
373387
FUNCTION(UnownedRetainN, swift_unownedRetain_n,
374388
RegisterPreservingCC,
@@ -389,13 +403,27 @@ FUNCTION(NativeStrongRetainUnowned, swift_unownedRetainStrong, RegisterPreservin
389403
ARGS(RefCountedPtrTy),
390404
ATTRS(NoUnwind))
391405

406+
// void swift_nonatomic_unownedRetainStrong(void *ptr);
407+
FUNCTION(NonAtomicNativeStrongRetainUnowned, swift_nonatomic_unownedRetainStrong,
408+
RegisterPreservingCC,
409+
RETURNS(VoidTy),
410+
ARGS(RefCountedPtrTy),
411+
ATTRS(NoUnwind))
412+
392413
// void swift_unownedRetainStrongAndRelease(void *ptr);
393414
FUNCTION(NativeStrongRetainAndUnownedRelease,
394415
swift_unownedRetainStrongAndRelease, RegisterPreservingCC,
395416
RETURNS(VoidTy),
396417
ARGS(RefCountedPtrTy),
397418
ATTRS(NoUnwind))
398419

420+
// void swift_nonatomic_unownedRetainStrongAndRelease(void *ptr);
421+
FUNCTION(NonAtomicNativeStrongRetainAndUnownedRelease,
422+
swift_nonatomic_unownedRetainStrongAndRelease, RegisterPreservingCC,
423+
RETURNS(VoidTy),
424+
ARGS(RefCountedPtrTy),
425+
ATTRS(NoUnwind))
426+
399427
// void swift_weakDestroy(WeakReference *object);
400428
FUNCTION(NativeWeakDestroy, swift_weakDestroy, DefaultCC,
401429
RETURNS(VoidTy),

include/swift/SIL/SILBuilder.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -856,9 +856,10 @@ class SILBuilder {
856856
}
857857

858858
UnmanagedAutoreleaseValueInst *
859-
createUnmanagedAutoreleaseValue(SILLocation Loc, SILValue operand) {
859+
createUnmanagedAutoreleaseValue(SILLocation Loc, SILValue operand,
860+
Atomicity atomicity) {
860861
return insert(new (F.getModule()) UnmanagedAutoreleaseValueInst(
861-
getSILDebugLocation(Loc), operand));
862+
getSILDebugLocation(Loc), operand, atomicity));
862863
}
863864

864865
SetDeallocatingInst *createSetDeallocating(SILLocation Loc,
@@ -1529,6 +1530,11 @@ class SILBuilder {
15291530
// Memory management helpers
15301531
//===--------------------------------------------------------------------===//
15311532

1533+
/// Returns the default atomicity of the module.
1534+
Atomicity getDefaultAtomicity() {
1535+
return getModule().isDefaultAtomic() ? Atomicity::Atomic : Atomicity::NonAtomic;
1536+
}
1537+
15321538
/// Try to fold a destroy_addr operation into the previous instructions, or
15331539
/// generate an explicit one if that fails. If this inserts a new
15341540
/// instruction, it returns it, otherwise it returns null.

include/swift/SIL/SILCloner.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,8 @@ void SILCloner<ImplClass>::visitUnmanagedAutoreleaseValueInst(
12381238
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
12391239
doPostProcess(
12401240
Inst, getBuilder().createUnmanagedAutoreleaseValue(
1241-
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
1241+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1242+
Inst->getAtomicity()));
12421243
}
12431244

12441245
template<typename ImplClass>

include/swift/SIL/SILInstruction.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -3046,8 +3046,11 @@ class UnmanagedAutoreleaseValueInst
30463046
/*HasValue*/ false> {
30473047
friend SILBuilder;
30483048

3049-
UnmanagedAutoreleaseValueInst(SILDebugLocation DebugLoc, SILValue operand)
3050-
: UnaryInstructionBase(DebugLoc, operand) {}
3049+
UnmanagedAutoreleaseValueInst(SILDebugLocation DebugLoc, SILValue operand,
3050+
Atomicity atomicity)
3051+
: UnaryInstructionBase(DebugLoc, operand) {
3052+
setAtomicity(atomicity);
3053+
}
30513054
};
30523055

30533056
/// Transfers ownership of a loadable value to the current autorelease pool.

include/swift/SIL/SILModule.h

+5
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,11 @@ class SILModule {
642642

643643
/// Returns true if the builtin or intrinsic is no-return.
644644
bool isNoReturnBuiltinOrIntrinsic(Identifier Name);
645+
646+
/// Returns true if the default atomicity of the module is Atomic.
647+
bool isDefaultAtomic() const {
648+
return ! getOptions().AssumeSingleThreaded;
649+
}
645650
};
646651

647652
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SILModule &M){

lib/IRGen/GenClass.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ static bool getInstanceSizeByMethod(IRGenFunction &IGF,
795795

796796
// Retain 'self' if necessary.
797797
if (fnType->getParameters()[0].isConsumed()) {
798-
IGF.emitNativeStrongRetain(selfValue);
798+
IGF.emitNativeStrongRetain(selfValue, IGF.getDefaultAtomicity());
799799
}
800800

801801
// Adjust down to the defining subclass type if necessary.

lib/IRGen/GenEnum.cpp

+12-12
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,7 @@ namespace {
12811281
assert(TIK >= Loadable);
12821282
Explosion tmp;
12831283
loadAsTake(IGF, addr, tmp);
1284-
copy(IGF, tmp, e, Atomicity::Atomic);
1284+
copy(IGF, tmp, e, IGF.getDefaultAtomicity());
12851285
}
12861286

12871287
void assign(IRGenFunction &IGF, Explosion &e, Address addr) const override {
@@ -1291,7 +1291,7 @@ namespace {
12911291
loadAsTake(IGF, addr, old);
12921292
initialize(IGF, e, addr);
12931293
if (!isPOD(ResilienceExpansion::Maximal))
1294-
consume(IGF, old, Atomicity::Atomic);
1294+
consume(IGF, old, IGF.getDefaultAtomicity());
12951295
}
12961296

12971297
void initialize(IRGenFunction &IGF, Explosion &e, Address addr)
@@ -1503,7 +1503,7 @@ namespace {
15031503
Explosion payloadCopy;
15041504
auto &loadableTI = getLoadablePayloadTypeInfo();
15051505
loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0);
1506-
loadableTI.copy(IGF, payloadValue, payloadCopy, Atomicity::Atomic);
1506+
loadableTI.copy(IGF, payloadValue, payloadCopy, IGF.getDefaultAtomicity());
15071507
(void)payloadCopy.claimAll(); // FIXME: repack if not bit-identical
15081508
}
15091509

@@ -1536,7 +1536,7 @@ namespace {
15361536
Explosion payloadValue;
15371537
auto &loadableTI = getLoadablePayloadTypeInfo();
15381538
loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0);
1539-
loadableTI.consume(IGF, payloadValue, Atomicity::Atomic);
1539+
loadableTI.consume(IGF, payloadValue, IGF.getDefaultAtomicity());
15401540
}
15411541

15421542
IGF.Builder.CreateBr(endBB);
@@ -2208,7 +2208,7 @@ namespace {
22082208
llvm::Value *ptr) const {
22092209
switch (CopyDestroyKind) {
22102210
case NullableRefcounted:
2211-
IGF.emitStrongRetain(ptr, Refcounting, Atomicity::Atomic);
2211+
IGF.emitStrongRetain(ptr, Refcounting, IGF.getDefaultAtomicity());
22122212
return;
22132213
case POD:
22142214
case Normal:
@@ -2232,7 +2232,7 @@ namespace {
22322232
llvm::Value *ptr) const {
22332233
switch (CopyDestroyKind) {
22342234
case NullableRefcounted:
2235-
IGF.emitStrongRelease(ptr, Refcounting, Atomicity::Atomic);
2235+
IGF.emitStrongRelease(ptr, Refcounting, IGF.getDefaultAtomicity());
22362236
return;
22372237
case POD:
22382238
case Normal:
@@ -2917,7 +2917,7 @@ namespace {
29172917
projectPayloadValue(IGF, parts.payload, tagIndex, lti, value);
29182918

29192919
Explosion tmp;
2920-
lti.copy(IGF, value, tmp, Atomicity::Atomic);
2920+
lti.copy(IGF, value, tmp, IGF.getDefaultAtomicity());
29212921
(void)tmp.claimAll(); // FIXME: repack if not bit-identical
29222922
});
29232923

@@ -2942,7 +2942,7 @@ namespace {
29422942
Explosion value;
29432943
projectPayloadValue(IGF, parts.payload, tagIndex, lti, value);
29442944

2945-
lti.consume(IGF, value, Atomicity::Atomic);
2945+
lti.consume(IGF, value, IGF.getDefaultAtomicity());
29462946
});
29472947

29482948
IGF.Builder.CreateRetVoid();
@@ -3119,7 +3119,7 @@ namespace {
31193119
llvm::Value *ptr) const {
31203120
switch (CopyDestroyKind) {
31213121
case TaggedRefcounted:
3122-
IGF.emitStrongRetain(ptr, Refcounting, Atomicity::Atomic);
3122+
IGF.emitStrongRetain(ptr, Refcounting, IGF.getDefaultAtomicity());
31233123
return;
31243124
case POD:
31253125
case BitwiseTakable:
@@ -3145,7 +3145,7 @@ namespace {
31453145
llvm::Value *ptr) const {
31463146
switch (CopyDestroyKind) {
31473147
case TaggedRefcounted:
3148-
IGF.emitStrongRelease(ptr, Refcounting, Atomicity::Atomic);
3148+
IGF.emitStrongRelease(ptr, Refcounting, IGF.getDefaultAtomicity());
31493149
return;
31503150
case POD:
31513151
case BitwiseTakable:
@@ -4060,7 +4060,7 @@ namespace {
40604060

40614061
loadAsTake(IGF, dest, tmpOld);
40624062
initialize(IGF, tmpSrc, dest);
4063-
consume(IGF, tmpOld, Atomicity::Atomic);
4063+
consume(IGF, tmpOld, IGF.getDefaultAtomicity());
40644064
return;
40654065
}
40664066

@@ -4254,7 +4254,7 @@ namespace {
42544254
if (TI->isLoadable()) {
42554255
Explosion tmp;
42564256
loadAsTake(IGF, addr, tmp);
4257-
consume(IGF, tmp, Atomicity::Atomic);
4257+
consume(IGF, tmp, IGF.getDefaultAtomicity());
42584258
return;
42594259
}
42604260

lib/IRGen/GenExistential.cpp

+18-13
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ class ScalarExistentialTypeInfoBase :
750750
Explosion &out) const override {
751751
// Load the instance pointer, which is unknown-refcounted.
752752
llvm::Value *instance = asDerived().loadValue(IGF, address);
753-
asDerived().emitValueRetain(IGF, instance, Atomicity::Atomic);
753+
asDerived().emitValueRetain(IGF, instance, IGF.getDefaultAtomicity());
754754
out.add(instance);
755755

756756
// Load the witness table pointers.
@@ -772,7 +772,7 @@ class ScalarExistentialTypeInfoBase :
772772
Address instanceAddr = asDerived().projectValue(IGF, address);
773773
llvm::Value *old = IGF.Builder.CreateLoad(instanceAddr);
774774
IGF.Builder.CreateStore(e.claimNext(), instanceAddr);
775-
asDerived().emitValueRelease(IGF, old, Atomicity::Atomic);
775+
asDerived().emitValueRelease(IGF, old, IGF.getDefaultAtomicity());
776776

777777
// Store the witness table pointers.
778778
asDerived().emitStoreOfTables(IGF, e, address);
@@ -821,7 +821,7 @@ class ScalarExistentialTypeInfoBase :
821821

822822
void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {
823823
llvm::Value *value = asDerived().loadValue(IGF, addr);
824-
asDerived().emitValueRelease(IGF, value, Atomicity::Atomic);
824+
asDerived().emitValueRelease(IGF, value, IGF.getDefaultAtomicity());
825825
}
826826

827827
void packIntoEnumPayload(IRGenFunction &IGF,
@@ -937,12 +937,12 @@ class LoadableUnownedClassExistentialTypeInfo final
937937

938938
void emitValueRetain(IRGenFunction &IGF, llvm::Value *value,
939939
Atomicity atomicity) const {
940-
IGF.emitUnownedRetain(value, Refcounting);
940+
IGF.emitUnownedRetain(value, Refcounting, atomicity);
941941
}
942942

943943
void emitValueRelease(IRGenFunction &IGF, llvm::Value *value,
944944
Atomicity atomicity) const {
945-
IGF.emitUnownedRelease(value, Refcounting);
945+
IGF.emitUnownedRelease(value, Refcounting, atomicity);
946946
}
947947

948948
void emitValueFixLifetime(IRGenFunction &IGF, llvm::Value *value) const {
@@ -1077,24 +1077,29 @@ class ClassExistentialTypeInfo final
10771077
(void)e.claim(getNumStoredProtocols());
10781078
}
10791079

1080-
void strongRetainUnowned(IRGenFunction &IGF, Explosion &e) const override {
1081-
IGF.emitStrongRetainUnowned(e.claimNext(), Refcounting);
1080+
void strongRetainUnowned(IRGenFunction &IGF, Explosion &e,
1081+
Atomicity atomicity) const override {
1082+
IGF.emitStrongRetainUnowned(e.claimNext(), Refcounting, atomicity);
10821083
(void)e.claim(getNumStoredProtocols());
10831084
}
10841085

10851086
void strongRetainUnownedRelease(IRGenFunction &IGF,
1086-
Explosion &e) const override {
1087-
IGF.emitStrongRetainAndUnownedRelease(e.claimNext(), Refcounting);
1087+
Explosion &e,
1088+
Atomicity atomicity) const override {
1089+
IGF.emitStrongRetainAndUnownedRelease(e.claimNext(), Refcounting,
1090+
atomicity);
10881091
(void)e.claim(getNumStoredProtocols());
10891092
}
10901093

1091-
void unownedRetain(IRGenFunction &IGF, Explosion &e) const override {
1092-
IGF.emitUnownedRetain(e.claimNext(), Refcounting);
1094+
void unownedRetain(IRGenFunction &IGF, Explosion &e,
1095+
Atomicity atomicity) const override {
1096+
IGF.emitUnownedRetain(e.claimNext(), Refcounting, atomicity);
10931097
(void)e.claim(getNumStoredProtocols());
10941098
}
10951099

1096-
void unownedRelease(IRGenFunction &IGF, Explosion &e) const override {
1097-
IGF.emitUnownedRelease(e.claimNext(), Refcounting);
1100+
void unownedRelease(IRGenFunction &IGF, Explosion &e,
1101+
Atomicity atomicity) const override {
1102+
IGF.emitUnownedRelease(e.claimNext(), Refcounting, atomicity);
10981103
(void)e.claim(getNumStoredProtocols());
10991104
}
11001105

0 commit comments

Comments
 (0)