Skip to content

Commit 0d4ab4a

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 4f7c8f4 commit 0d4ab4a

25 files changed

+758
-328
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 74 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,10 @@ namespace {
396396
}
397397

398398
void loadAsCopy(IRGenFunction &IGF, Address addr,
399-
Explosion &e) const override {
399+
Explosion &e, Atomicity atomicity) const override {
400400
if (!getLoadableSingleton()) return;
401-
getLoadableSingleton()->loadAsCopy(IGF, getSingletonAddress(IGF, addr),e);
401+
getLoadableSingleton()->loadAsCopy(IGF, getSingletonAddress(IGF, addr), e,
402+
atomicity);
402403
}
403404

404405
void loadForSwitch(IRGenFunction &IGF, Address addr, Explosion &e) const {
@@ -466,29 +467,32 @@ 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

482-
void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {
483-
if (getSingleton() && !getSingleton()->isPOD(ResilienceExpansion::Maximal))
486+
void destroy(IRGenFunction &IGF, Address addr, SILType T,
487+
Atomicity atomicity) const override {
488+
if (getSingleton() &&
489+
!getSingleton()->isPOD(ResilienceExpansion::Maximal))
484490
getSingleton()->destroy(IGF, getSingletonAddress(IGF, addr),
485-
getSingletonType(IGF.IGM, T));
491+
getSingletonType(IGF.IGM, T), atomicity);
486492
}
487493

488-
void packIntoEnumPayload(IRGenFunction &IGF,
489-
EnumPayload &payload,
490-
Explosion &in,
491-
unsigned offset) const override {
494+
void packIntoEnumPayload(IRGenFunction &IGF, EnumPayload &payload,
495+
Explosion &in, unsigned offset) const override {
492496
if (getLoadableSingleton())
493497
return getLoadableSingleton()->packIntoEnumPayload(IGF, payload,
494498
in, offset);
@@ -830,8 +834,10 @@ namespace {
830834
return IGF.Builder.CreateStructGEP(addr, 0, Size(0));
831835
}
832836

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

837843
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
@@ -1190,12 +1196,12 @@ namespace {
11901196
loadForSwitch(IGF, addr, e);
11911197
}
11921198

1193-
void loadAsCopy(IRGenFunction &IGF, Address addr, Explosion &e)
1194-
const override {
1199+
void loadAsCopy(IRGenFunction &IGF, Address addr, Explosion &e,
1200+
Atomicity atomicity) const override {
11951201
assert(TIK >= Loadable);
11961202
Explosion tmp;
11971203
loadAsTake(IGF, addr, tmp);
1198-
copy(IGF, tmp, e);
1204+
copy(IGF, tmp, e, atomicity);
11991205
}
12001206

12011207
void assign(IRGenFunction &IGF, Explosion &e, Address addr) const override {
@@ -1205,7 +1211,7 @@ namespace {
12051211
loadAsTake(IGF, addr, old);
12061212
initialize(IGF, e, addr);
12071213
if (!isPOD(ResilienceExpansion::Maximal))
1208-
consume(IGF, old);
1214+
consume(IGF, old, Atomicity::Atomic);
12091215
}
12101216

12111217
void initialize(IRGenFunction &IGF, Explosion &e, Address addr)
@@ -2012,7 +2018,7 @@ namespace {
20122018
llvm::Value *ptr) const {
20132019
switch (CopyDestroyKind) {
20142020
case NullableRefcounted:
2015-
IGF.emitStrongRetain(ptr, Refcounting);
2021+
IGF.emitStrongRetain(ptr, Refcounting, Atomicity::Atomic);
20162022
return;
20172023
case POD:
20182024
case Normal:
@@ -2036,7 +2042,7 @@ namespace {
20362042
llvm::Value *ptr) const {
20372043
switch (CopyDestroyKind) {
20382044
case NullableRefcounted:
2039-
IGF.emitStrongRelease(ptr, Refcounting);
2045+
IGF.emitStrongRelease(ptr, Refcounting, Atomicity::Atomic);
20402046
return;
20412047
case POD:
20422048
case Normal:
@@ -2045,8 +2051,8 @@ namespace {
20452051
}
20462052

20472053
public:
2048-
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest)
2049-
const override {
2054+
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest,
2055+
Atomicity atomicity) const override {
20502056
assert(TIK >= Loadable);
20512057

20522058
switch (CopyDestroyKind) {
@@ -2068,7 +2074,7 @@ namespace {
20682074
Explosion payloadCopy;
20692075
auto &loadableTI = getLoadablePayloadTypeInfo();
20702076
loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0);
2071-
loadableTI.copy(IGF, payloadValue, payloadCopy);
2077+
loadableTI.copy(IGF, payloadValue, payloadCopy, Atomicity::Atomic);
20722078
payloadCopy.claimAll(); // FIXME: repack if not bit-identical
20732079
}
20742080

@@ -2093,7 +2099,8 @@ namespace {
20932099
}
20942100
}
20952101

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

20992106
switch (CopyDestroyKind) {
@@ -2116,7 +2123,7 @@ namespace {
21162123
Explosion payloadValue;
21172124
auto &loadableTI = getLoadablePayloadTypeInfo();
21182125
loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0);
2119-
loadableTI.consume(IGF, payloadValue);
2126+
loadableTI.consume(IGF, payloadValue, Atomicity::Atomic);
21202127
}
21212128

21222129
IGF.Builder.CreateBr(endBB);
@@ -2179,7 +2186,8 @@ namespace {
21792186

21802187
}
21812188

2182-
void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {
2189+
void destroy(IRGenFunction &IGF, Address addr, SILType T,
2190+
Atomicity atomicity) const override {
21832191
switch (CopyDestroyKind) {
21842192
case POD:
21852193
return;
@@ -2193,7 +2201,8 @@ namespace {
21932201
// If there is, project and destroy it.
21942202
Address payloadAddr = projectPayloadData(IGF, addr);
21952203
getPayloadTypeInfo().destroy(IGF, payloadAddr,
2196-
getPayloadType(IGF.IGM, T));
2204+
getPayloadType(IGF.IGM, T),
2205+
Atomicity::Atomic);
21972206

21982207
IGF.Builder.CreateBr(endBB);
21992208
IGF.Builder.emitBlock(endBB);
@@ -2296,7 +2305,8 @@ namespace {
22962305
IGF.Builder.emitBlock(destNoSrcPayloadBB);
22972306
{
22982307
ConditionalDominanceScope destNoSrcCondition(IGF);
2299-
getPayloadTypeInfo().destroy(IGF, destData, PayloadT);
2308+
getPayloadTypeInfo().destroy(IGF, destData, PayloadT,
2309+
Atomicity::Atomic);
23002310
emitPrimitiveCopy(IGF, dest, src, T);
23012311
IGF.Builder.CreateBr(endBB);
23022312
}
@@ -2883,7 +2893,7 @@ namespace {
28832893
llvm::Value *ptr) const {
28842894
switch (CopyDestroyKind) {
28852895
case TaggedRefcounted:
2886-
IGF.emitStrongRetain(ptr, Refcounting);
2896+
IGF.emitStrongRetain(ptr, Refcounting, Atomicity::Atomic);
28872897
return;
28882898
case POD:
28892899
case BitwiseTakable:
@@ -2909,7 +2919,7 @@ namespace {
29092919
llvm::Value *ptr) const {
29102920
switch (CopyDestroyKind) {
29112921
case TaggedRefcounted:
2912-
IGF.emitStrongRelease(ptr, Refcounting);
2922+
IGF.emitStrongRelease(ptr, Refcounting, Atomicity::Atomic);
29132923
return;
29142924
case POD:
29152925
case BitwiseTakable:
@@ -3618,8 +3628,8 @@ namespace {
36183628
emitNoPayloadInjection(IGF, out, emptyI - ElementsWithNoPayload.begin());
36193629
}
36203630

3621-
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest)
3622-
const override {
3631+
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest,
3632+
Atomicity atomicity) const override {
36233633
assert(TIK >= Loadable);
36243634

36253635
switch (CopyDestroyKind) {
@@ -3638,7 +3648,7 @@ namespace {
36383648
projectPayloadValue(IGF, parts.payload, tagIndex, lti, value);
36393649

36403650
Explosion tmp;
3641-
lti.copy(IGF, value, tmp);
3651+
lti.copy(IGF, value, tmp, Atomicity::Atomic);
36423652
tmp.claimAll(); // FIXME: repack if not bit-identical
36433653
});
36443654

@@ -3671,7 +3681,8 @@ namespace {
36713681

36723682
}
36733683

3674-
void consume(IRGenFunction &IGF, Explosion &src) const override {
3684+
void consume(IRGenFunction &IGF, Explosion &src,
3685+
Atomicity atomicity) const override {
36753686
assert(TIK >= Loadable);
36763687

36773688
switch (CopyDestroyKind) {
@@ -3689,7 +3700,7 @@ namespace {
36893700
Explosion value;
36903701
projectPayloadValue(IGF, parts.payload, tagIndex, lti, value);
36913702

3692-
lti.consume(IGF, value);
3703+
lti.consume(IGF, value, Atomicity::Atomic);
36933704
});
36943705
return;
36953706
}
@@ -3766,11 +3777,11 @@ namespace {
37663777
if (isTake)
37673778
loadAsTake(IGF, src, tmpSrc);
37683779
else
3769-
loadAsCopy(IGF, src, tmpSrc);
3780+
loadAsCopy(IGF, src, tmpSrc, Atomicity::Atomic);
37703781

37713782
loadAsTake(IGF, dest, tmpOld);
37723783
initialize(IGF, tmpSrc, dest);
3773-
consume(IGF, tmpOld);
3784+
consume(IGF, tmpOld, Atomicity::Atomic);
37743785
return;
37753786
}
37763787

@@ -3785,7 +3796,7 @@ namespace {
37853796
ConditionalDominanceScope condition(IGF);
37863797

37873798
// Destroy the old value.
3788-
destroy(IGF, dest, T);
3799+
destroy(IGF, dest, T, Atomicity::Atomic);
37893800

37903801
// Reinitialize with the new value.
37913802
emitIndirectInitialize(IGF, dest, src, T, isTake);
@@ -3822,7 +3833,7 @@ namespace {
38223833
if (isTake)
38233834
loadAsTake(IGF, src, tmpSrc);
38243835
else
3825-
loadAsCopy(IGF, src, tmpSrc);
3836+
loadAsCopy(IGF, src, tmpSrc, Atomicity::Atomic);
38263837
initialize(IGF, tmpSrc, dest);
38273838
return;
38283839
}
@@ -3923,8 +3934,8 @@ namespace {
39233934
emitIndirectInitialize(IGF, dest, src, T, IsTake);
39243935
}
39253936

3926-
void destroy(IRGenFunction &IGF, Address addr, SILType T)
3927-
const override {
3937+
void destroy(IRGenFunction &IGF, Address addr, SILType T,
3938+
Atomicity atomicity) const override {
39283939
switch (CopyDestroyKind) {
39293940
case POD:
39303941
return;
@@ -3937,7 +3948,7 @@ namespace {
39373948
if (TI->isLoadable()) {
39383949
Explosion tmp;
39393950
loadAsTake(IGF, addr, tmp);
3940-
consume(IGF, tmp);
3951+
consume(IGF, tmp, Atomicity::Atomic);
39413952
return;
39423953
}
39433954

@@ -3951,7 +3962,7 @@ namespace {
39513962
Address dataAddr = IGF.Builder.CreateBitCast(addr,
39523963
elt.ti->getStorageType()->getPointerTo());
39533964
SILType payloadT = T.getEnumElementType(elt.decl, *IGF.IGM.SILMod);
3954-
elt.ti->destroy(IGF, dataAddr, payloadT);
3965+
elt.ti->destroy(IGF, dataAddr, payloadT, Atomicity::Atomic);
39553966
});
39563967
return;
39573968
}
@@ -4440,8 +4451,8 @@ namespace {
44404451
dest, src);
44414452
}
44424453

4443-
void destroy(IRGenFunction &IGF, Address addr, SILType T)
4444-
const override {
4454+
void destroy(IRGenFunction &IGF, Address addr, SILType T,
4455+
Atomicity atomicity) const override {
44454456
emitDestroyCall(IGF, T, addr);
44464457
}
44474458

@@ -4505,8 +4516,8 @@ namespace {
45054516
llvm_unreachable("resilient enums are always indirect");
45064517
}
45074518

4508-
void loadAsCopy(IRGenFunction &IGF, Address addr,
4509-
Explosion &e) const override {
4519+
void loadAsCopy(IRGenFunction &IGF, Address addr, Explosion &e,
4520+
Atomicity atomicity) const override {
45104521
llvm_unreachable("resilient enums are always indirect");
45114522
}
45124523

@@ -4530,12 +4541,13 @@ namespace {
45304541
llvm_unreachable("resilient enums are always indirect");
45314542
}
45324543

4533-
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest)
4534-
const override {
4544+
void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest,
4545+
Atomicity atomicity) const override {
45354546
llvm_unreachable("resilient enums are always indirect");
45364547
}
45374548

4538-
void consume(IRGenFunction &IGF, Explosion &src) const override {
4549+
void consume(IRGenFunction &IGF, Explosion &src,
4550+
Atomicity atomicity) const override {
45394551
llvm_unreachable("resilient enums are always indirect");
45404552
}
45414553

@@ -4788,8 +4800,9 @@ namespace {
47884800
void getSchema(ExplosionSchema &s) const override {
47894801
return Strategy.getSchema(s);
47904802
}
4791-
void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {
4792-
return Strategy.destroy(IGF, addr, T);
4803+
void destroy(IRGenFunction &IGF, Address addr, SILType T,
4804+
Atomicity atomicity) const override {
4805+
return Strategy.destroy(IGF, addr, T, atomicity);
47934806
}
47944807
void initializeFromParams(IRGenFunction &IGF, Explosion &params,
47954808
Address dest, SILType T) const override {
@@ -4876,8 +4889,8 @@ namespace {
48764889
return Strategy.getExplosionSize();
48774890
}
48784891
void loadAsCopy(IRGenFunction &IGF, Address addr,
4879-
Explosion &e) const override {
4880-
return Strategy.loadAsCopy(IGF, addr, e);
4892+
Explosion &e, Atomicity atomicity) const override {
4893+
return Strategy.loadAsCopy(IGF, addr, e, atomicity);
48814894
}
48824895
void loadAsTake(IRGenFunction &IGF, Address addr,
48834896
Explosion &e) const override {
@@ -4896,11 +4909,12 @@ namespace {
48964909
return Strategy.reexplode(IGF, src, dest);
48974910
}
48984911
void copy(IRGenFunction &IGF, Explosion &src,
4899-
Explosion &dest) const override {
4900-
return Strategy.copy(IGF, src, dest);
4912+
Explosion &dest, Atomicity atomicity) const override {
4913+
return Strategy.copy(IGF, src, dest, atomicity);
49014914
}
4902-
void consume(IRGenFunction &IGF, Explosion &src) const override {
4903-
return Strategy.consume(IGF, src);
4915+
void consume(IRGenFunction &IGF, Explosion &src,
4916+
Atomicity atomicity) const override {
4917+
return Strategy.consume(IGF, src, atomicity);
49044918
}
49054919
void fixLifetime(IRGenFunction &IGF, Explosion &src) const override {
49064920
return Strategy.fixLifetime(IGF, src);

0 commit comments

Comments
 (0)