Skip to content

Commit d8e28bb

Browse files
committed
Handle the [nonatomic] attribute in IRGen and LLVM passes.
Properly lower reference counting SIL instructions with nonatomic attribute as invocations of corresponding non-atomic reference counting runtime functions.
1 parent 2e77b39 commit d8e28bb

20 files changed

+677
-272
lines changed

Diff for: lib/IRGen/GenEnum.cpp

+52-45
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,8 @@ namespace {
398398
void loadAsCopy(IRGenFunction &IGF, Address addr,
399399
Explosion &e) const override {
400400
if (!getLoadableSingleton()) return;
401-
getLoadableSingleton()->loadAsCopy(IGF, getSingletonAddress(IGF, addr),e);
401+
getLoadableSingleton()->loadAsCopy(IGF, getSingletonAddress(IGF, addr),
402+
e);
402403
}
403404

404405
void loadForSwitch(IRGenFunction &IGF, Address addr, Explosion &e) const {
@@ -466,29 +467,31 @@ namespace {
466467
if (getLoadableSingleton()) getLoadableSingleton()->reexplode(IGF, src, dest);
467468
}
468469

469-
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest)
470-
const override {
471-
if (getLoadableSingleton()) getLoadableSingleton()->copy(IGF, src, dest);
470+
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest,
471+
Atomicity atomicity) const override {
472+
if (getLoadableSingleton())
473+
getLoadableSingleton()->copy(IGF, src, dest, atomicity);
472474
}
473475

474-
void consume(IRGenFunction &IGF, Explosion &src) const override {
475-
if (getLoadableSingleton()) getLoadableSingleton()->consume(IGF, src);
476+
void consume(IRGenFunction &IGF, Explosion &src,
477+
Atomicity atomicity) const override {
478+
if (getLoadableSingleton())
479+
getLoadableSingleton()->consume(IGF, src, atomicity);
476480
}
477481

478482
void fixLifetime(IRGenFunction &IGF, Explosion &src) const override {
479483
if (getLoadableSingleton()) getLoadableSingleton()->fixLifetime(IGF, src);
480484
}
481485

482486
void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {
483-
if (getSingleton() && !getSingleton()->isPOD(ResilienceExpansion::Maximal))
487+
if (getSingleton() &&
488+
!getSingleton()->isPOD(ResilienceExpansion::Maximal))
484489
getSingleton()->destroy(IGF, getSingletonAddress(IGF, addr),
485490
getSingletonType(IGF.IGM, T));
486491
}
487492

488-
void packIntoEnumPayload(IRGenFunction &IGF,
489-
EnumPayload &payload,
490-
Explosion &in,
491-
unsigned offset) const override {
493+
void packIntoEnumPayload(IRGenFunction &IGF, EnumPayload &payload,
494+
Explosion &in, unsigned offset) const override {
492495
if (getLoadableSingleton())
493496
return getLoadableSingleton()->packIntoEnumPayload(IGF, payload,
494497
in, offset);
@@ -830,8 +833,10 @@ namespace {
830833
return IGF.Builder.CreateStructGEP(addr, 0, Size(0));
831834
}
832835

833-
void emitScalarRetain(IRGenFunction &IGF, llvm::Value *value) const {}
834-
void emitScalarRelease(IRGenFunction &IGF, llvm::Value *value) const {}
836+
void emitScalarRetain(IRGenFunction &IGF, llvm::Value *value,
837+
Atomicity atomicity) const {}
838+
void emitScalarRelease(IRGenFunction &IGF, llvm::Value *value,
839+
Atomicity atomicity) const {}
835840
void emitScalarFixLifetime(IRGenFunction &IGF, llvm::Value *value) const {}
836841

837842
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
@@ -1190,12 +1195,12 @@ namespace {
11901195
loadForSwitch(IGF, addr, e);
11911196
}
11921197

1193-
void loadAsCopy(IRGenFunction &IGF, Address addr, Explosion &e)
1194-
const override {
1198+
void loadAsCopy(IRGenFunction &IGF, Address addr,
1199+
Explosion &e) const override {
11951200
assert(TIK >= Loadable);
11961201
Explosion tmp;
11971202
loadAsTake(IGF, addr, tmp);
1198-
copy(IGF, tmp, e);
1203+
copy(IGF, tmp, e, Atomicity::Atomic);
11991204
}
12001205

12011206
void assign(IRGenFunction &IGF, Explosion &e, Address addr) const override {
@@ -1205,7 +1210,7 @@ namespace {
12051210
loadAsTake(IGF, addr, old);
12061211
initialize(IGF, e, addr);
12071212
if (!isPOD(ResilienceExpansion::Maximal))
1208-
consume(IGF, old);
1213+
consume(IGF, old, Atomicity::Atomic);
12091214
}
12101215

12111216
void initialize(IRGenFunction &IGF, Explosion &e, Address addr)
@@ -2012,7 +2017,7 @@ namespace {
20122017
llvm::Value *ptr) const {
20132018
switch (CopyDestroyKind) {
20142019
case NullableRefcounted:
2015-
IGF.emitStrongRetain(ptr, Refcounting);
2020+
IGF.emitStrongRetain(ptr, Refcounting, Atomicity::Atomic);
20162021
return;
20172022
case POD:
20182023
case Normal:
@@ -2036,7 +2041,7 @@ namespace {
20362041
llvm::Value *ptr) const {
20372042
switch (CopyDestroyKind) {
20382043
case NullableRefcounted:
2039-
IGF.emitStrongRelease(ptr, Refcounting);
2044+
IGF.emitStrongRelease(ptr, Refcounting, Atomicity::Atomic);
20402045
return;
20412046
case POD:
20422047
case Normal:
@@ -2045,8 +2050,8 @@ namespace {
20452050
}
20462051

20472052
public:
2048-
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest)
2049-
const override {
2053+
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest,
2054+
Atomicity atomicity) const override {
20502055
assert(TIK >= Loadable);
20512056

20522057
switch (CopyDestroyKind) {
@@ -2068,7 +2073,7 @@ namespace {
20682073
Explosion payloadCopy;
20692074
auto &loadableTI = getLoadablePayloadTypeInfo();
20702075
loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0);
2071-
loadableTI.copy(IGF, payloadValue, payloadCopy);
2076+
loadableTI.copy(IGF, payloadValue, payloadCopy, Atomicity::Atomic);
20722077
payloadCopy.claimAll(); // FIXME: repack if not bit-identical
20732078
}
20742079

@@ -2093,7 +2098,8 @@ namespace {
20932098
}
20942099
}
20952100

2096-
void consume(IRGenFunction &IGF, Explosion &src) const override {
2101+
void consume(IRGenFunction &IGF, Explosion &src,
2102+
Atomicity atomicity) const override {
20972103
assert(TIK >= Loadable);
20982104

20992105
switch (CopyDestroyKind) {
@@ -2116,7 +2122,7 @@ namespace {
21162122
Explosion payloadValue;
21172123
auto &loadableTI = getLoadablePayloadTypeInfo();
21182124
loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0);
2119-
loadableTI.consume(IGF, payloadValue);
2125+
loadableTI.consume(IGF, payloadValue, Atomicity::Atomic);
21202126
}
21212127

21222128
IGF.Builder.CreateBr(endBB);
@@ -2883,7 +2889,7 @@ namespace {
28832889
llvm::Value *ptr) const {
28842890
switch (CopyDestroyKind) {
28852891
case TaggedRefcounted:
2886-
IGF.emitStrongRetain(ptr, Refcounting);
2892+
IGF.emitStrongRetain(ptr, Refcounting, Atomicity::Atomic);
28872893
return;
28882894
case POD:
28892895
case BitwiseTakable:
@@ -2909,7 +2915,7 @@ namespace {
29092915
llvm::Value *ptr) const {
29102916
switch (CopyDestroyKind) {
29112917
case TaggedRefcounted:
2912-
IGF.emitStrongRelease(ptr, Refcounting);
2918+
IGF.emitStrongRelease(ptr, Refcounting, Atomicity::Atomic);
29132919
return;
29142920
case POD:
29152921
case BitwiseTakable:
@@ -3618,8 +3624,8 @@ namespace {
36183624
emitNoPayloadInjection(IGF, out, emptyI - ElementsWithNoPayload.begin());
36193625
}
36203626

3621-
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest)
3622-
const override {
3627+
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest,
3628+
Atomicity atomicity) const override {
36233629
assert(TIK >= Loadable);
36243630

36253631
switch (CopyDestroyKind) {
@@ -3638,7 +3644,7 @@ namespace {
36383644
projectPayloadValue(IGF, parts.payload, tagIndex, lti, value);
36393645

36403646
Explosion tmp;
3641-
lti.copy(IGF, value, tmp);
3647+
lti.copy(IGF, value, tmp, Atomicity::Atomic);
36423648
tmp.claimAll(); // FIXME: repack if not bit-identical
36433649
});
36443650

@@ -3671,7 +3677,8 @@ namespace {
36713677

36723678
}
36733679

3674-
void consume(IRGenFunction &IGF, Explosion &src) const override {
3680+
void consume(IRGenFunction &IGF, Explosion &src,
3681+
Atomicity atomicity) const override {
36753682
assert(TIK >= Loadable);
36763683

36773684
switch (CopyDestroyKind) {
@@ -3689,7 +3696,7 @@ namespace {
36893696
Explosion value;
36903697
projectPayloadValue(IGF, parts.payload, tagIndex, lti, value);
36913698

3692-
lti.consume(IGF, value);
3699+
lti.consume(IGF, value, Atomicity::Atomic);
36933700
});
36943701
return;
36953702
}
@@ -3770,7 +3777,7 @@ namespace {
37703777

37713778
loadAsTake(IGF, dest, tmpOld);
37723779
initialize(IGF, tmpSrc, dest);
3773-
consume(IGF, tmpOld);
3780+
consume(IGF, tmpOld, Atomicity::Atomic);
37743781
return;
37753782
}
37763783

@@ -3923,8 +3930,7 @@ namespace {
39233930
emitIndirectInitialize(IGF, dest, src, T, IsTake);
39243931
}
39253932

3926-
void destroy(IRGenFunction &IGF, Address addr, SILType T)
3927-
const override {
3933+
void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {
39283934
switch (CopyDestroyKind) {
39293935
case POD:
39303936
return;
@@ -3937,7 +3943,7 @@ namespace {
39373943
if (TI->isLoadable()) {
39383944
Explosion tmp;
39393945
loadAsTake(IGF, addr, tmp);
3940-
consume(IGF, tmp);
3946+
consume(IGF, tmp, Atomicity::Atomic);
39413947
return;
39423948
}
39433949

@@ -4440,8 +4446,7 @@ namespace {
44404446
dest, src);
44414447
}
44424448

4443-
void destroy(IRGenFunction &IGF, Address addr, SILType T)
4444-
const override {
4449+
void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {
44454450
emitDestroyCall(IGF, T, addr);
44464451
}
44474452

@@ -4506,7 +4511,7 @@ namespace {
45064511
}
45074512

45084513
void loadAsCopy(IRGenFunction &IGF, Address addr,
4509-
Explosion &e) const override {
4514+
Explosion &e) const override {
45104515
llvm_unreachable("resilient enums are always indirect");
45114516
}
45124517

@@ -4530,12 +4535,13 @@ namespace {
45304535
llvm_unreachable("resilient enums are always indirect");
45314536
}
45324537

4533-
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest)
4534-
const override {
4538+
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest,
4539+
Atomicity atomicity) const override {
45354540
llvm_unreachable("resilient enums are always indirect");
45364541
}
45374542

4538-
void consume(IRGenFunction &IGF, Explosion &src) const override {
4543+
void consume(IRGenFunction &IGF, Explosion &src,
4544+
Atomicity atomicity) const override {
45394545
llvm_unreachable("resilient enums are always indirect");
45404546
}
45414547

@@ -4896,11 +4902,12 @@ namespace {
48964902
return Strategy.reexplode(IGF, src, dest);
48974903
}
48984904
void copy(IRGenFunction &IGF, Explosion &src,
4899-
Explosion &dest) const override {
4900-
return Strategy.copy(IGF, src, dest);
4905+
Explosion &dest, Atomicity atomicity) const override {
4906+
return Strategy.copy(IGF, src, dest, atomicity);
49014907
}
4902-
void consume(IRGenFunction &IGF, Explosion &src) const override {
4903-
return Strategy.consume(IGF, src);
4908+
void consume(IRGenFunction &IGF, Explosion &src,
4909+
Atomicity atomicity) const override {
4910+
return Strategy.consume(IGF, src, atomicity);
49044911
}
49054912
void fixLifetime(IRGenFunction &IGF, Explosion &src) const override {
49064913
return Strategy.fixLifetime(IGF, src);

Diff for: lib/IRGen/GenEnum.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ class EnumImplStrategy {
344344

345345
virtual void getSchema(ExplosionSchema &schema) const = 0;
346346
virtual void destroy(IRGenFunction &IGF, Address addr, SILType T) const = 0;
347-
347+
348348
virtual void initializeFromParams(IRGenFunction &IGF, Explosion &params,
349349
Address dest, SILType T) const;
350350

@@ -398,8 +398,9 @@ class EnumImplStrategy {
398398
virtual void reexplode(IRGenFunction &IGF, Explosion &src,
399399
Explosion &dest) const = 0;
400400
virtual void copy(IRGenFunction &IGF, Explosion &src,
401-
Explosion &dest) const = 0;
402-
virtual void consume(IRGenFunction &IGF, Explosion &src) const = 0;
401+
Explosion &dest, Atomicity atomicity) const = 0;
402+
virtual void consume(IRGenFunction &IGF, Explosion &src,
403+
Atomicity atomicity) const = 0;
403404
virtual void fixLifetime(IRGenFunction &IGF, Explosion &src) const = 0;
404405
virtual void packIntoEnumPayload(IRGenFunction &IGF,
405406
EnumPayload &payload,

0 commit comments

Comments
 (0)