Skip to content

Commit 6987c70

Browse files
Merge pull request #71686 from nate-chandler/bitwise-copyable/more-ti
[BitwiseCopyable] Use TypeInfo for conforming resilient types.
2 parents d6f9401 + d1bd039 commit 6987c70

File tree

5 files changed

+96
-73
lines changed

5 files changed

+96
-73
lines changed

lib/IRGen/GenArchetype.cpp

Lines changed: 1 addition & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -172,77 +172,6 @@ class FixedSizeArchetypeTypeInfo
172172
return new FixedSizeArchetypeTypeInfo(type, size, align, spareBits);
173173
}
174174
};
175-
176-
class BitwiseCopyableArchetypeTypeInfo
177-
: public WitnessSizedTypeInfo<BitwiseCopyableArchetypeTypeInfo> {
178-
using Self = BitwiseCopyableArchetypeTypeInfo;
179-
using Super = WitnessSizedTypeInfo<Self>;
180-
BitwiseCopyableArchetypeTypeInfo(llvm::Type *type,
181-
IsABIAccessible_t abiAccessible)
182-
: Super(type, Alignment(1), IsNotTriviallyDestroyable,
183-
IsNotBitwiseTakable, IsCopyable, abiAccessible) {}
184-
185-
public:
186-
static const BitwiseCopyableArchetypeTypeInfo *
187-
create(llvm::Type *type, IsABIAccessible_t abiAccessible) {
188-
return new Self(type, abiAccessible);
189-
}
190-
191-
void bitwiseCopy(IRGenFunction &IGF, Address destAddr, Address srcAddr,
192-
SILType T, bool isOutlined) const {
193-
IGF.Builder.CreateMemCpy(destAddr, srcAddr, getSize(IGF, T));
194-
}
195-
196-
void initializeWithTake(IRGenFunction &IGF, Address destAddr, Address srcAddr,
197-
SILType T, bool isOutlined) const override {
198-
bitwiseCopy(IGF, destAddr, srcAddr, T, isOutlined);
199-
}
200-
201-
void initializeWithCopy(IRGenFunction &IGF, Address destAddr, Address srcAddr,
202-
SILType T, bool isOutlined) const override {
203-
bitwiseCopy(IGF, destAddr, srcAddr, T, isOutlined);
204-
}
205-
206-
void assignWithCopy(IRGenFunction &IGF, Address destAddr, Address srcAddr,
207-
SILType T, bool isOutlined) const override {
208-
bitwiseCopy(IGF, destAddr, srcAddr, T, isOutlined);
209-
}
210-
211-
void assignWithTake(IRGenFunction &IGF, Address destAddr, Address srcAddr,
212-
SILType T, bool isOutlined) const override {
213-
bitwiseCopy(IGF, destAddr, srcAddr, T, isOutlined);
214-
}
215-
216-
void destroy(IRGenFunction &IGF, Address address, SILType T,
217-
bool isOutlined) const override {
218-
// BitwiseCopyable types are trivial, so destroy is a no-op.
219-
}
220-
221-
llvm::Value *getEnumTagSinglePayload(IRGenFunction &IGF,
222-
llvm::Value *numEmptyCases,
223-
Address enumAddr, SILType T,
224-
bool isOutlined) const override {
225-
return emitGetEnumTagSinglePayloadCall(IGF, T, numEmptyCases, enumAddr);
226-
}
227-
228-
void storeEnumTagSinglePayload(IRGenFunction &IGF, llvm::Value *whichCase,
229-
llvm::Value *numEmptyCases, Address enumAddr,
230-
SILType T, bool isOutlined) const override {
231-
emitStoreEnumTagSinglePayloadCall(IGF, T, whichCase, numEmptyCases,
232-
enumAddr);
233-
}
234-
235-
void collectMetadataForOutlining(OutliningMetadataCollector &collector,
236-
SILType T) const override {
237-
// We'll need formal type metadata for this archetype.
238-
collector.collectTypeMetadataForLayout(T);
239-
}
240-
241-
TypeLayoutEntry *buildTypeLayoutEntry(IRGenModule &IGM, SILType T,
242-
bool useStructLayouts) const override {
243-
return IGM.typeLayoutCache.getOrCreateArchetypeEntry(T.getObjectType());
244-
}
245-
};
246175
} // end anonymous namespace
247176

248177
/// Emit a single protocol witness table reference.
@@ -440,7 +369,7 @@ const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {
440369
// The protocol won't be present in swiftinterfaces from older SDKs.
441370
if (bitwiseCopyableProtocol && IGM.getSwiftModule()->lookupConformance(
442371
archetype, bitwiseCopyableProtocol)) {
443-
return BitwiseCopyableArchetypeTypeInfo::create(storageType, abiAccessible);
372+
return BitwiseCopyableTypeInfo::create(storageType, abiAccessible);
444373
}
445374

446375
return OpaqueArchetypeTypeInfo::create(storageType, abiAccessible);

lib/IRGen/GenEnum.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7198,6 +7198,14 @@ ResilientEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
71987198
EnumDecl *theEnum,
71997199
llvm::StructType *enumTy) {
72007200
auto abiAccessible = IsABIAccessible_t(TC.IGM.isTypeABIAccessible(Type));
7201+
auto *bitwiseCopyableProtocol =
7202+
IGM.getSwiftModule()->getASTContext().getProtocol(
7203+
KnownProtocolKind::BitwiseCopyable);
7204+
if (bitwiseCopyableProtocol &&
7205+
IGM.getSwiftModule()->lookupConformance(
7206+
theEnum->getDeclaredInterfaceType(), bitwiseCopyableProtocol)) {
7207+
return BitwiseCopyableTypeInfo::create(enumTy, abiAccessible);
7208+
}
72017209
auto copyable = !theEnum->canBeCopyable()
72027210
? IsNotCopyable : IsCopyable;
72037211
return registerEnumTypeInfo(

lib/IRGen/GenStruct.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,14 @@ const TypeInfo *TypeConverter::convertStructType(TypeBase *key, CanType type,
16901690
? IsNotCopyable : IsCopyable;
16911691
auto structAccessible =
16921692
IsABIAccessible_t(IGM.getSILModule().isTypeMetadataAccessible(type));
1693+
auto *bitwiseCopyableProtocol =
1694+
IGM.getSwiftModule()->getASTContext().getProtocol(
1695+
KnownProtocolKind::BitwiseCopyable);
1696+
if (bitwiseCopyableProtocol &&
1697+
IGM.getSwiftModule()->lookupConformance(D->getDeclaredInterfaceType(),
1698+
bitwiseCopyableProtocol)) {
1699+
return BitwiseCopyableTypeInfo::create(IGM.OpaqueTy, structAccessible);
1700+
}
16931701
return &getResilientStructTypeInfo(copyable, structAccessible);
16941702
}
16951703

lib/IRGen/GenTuple.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,13 @@ namespace {
520520

521521
const TypeInfo *TypeConverter::convertTupleType(TupleType *tuple) {
522522
if (tuple->containsPackExpansionType()) {
523+
auto *bitwiseCopyableProtocol =
524+
IGM.getSwiftModule()->getASTContext().getProtocol(
525+
KnownProtocolKind::BitwiseCopyable);
526+
if (bitwiseCopyableProtocol && IGM.getSwiftModule()->lookupConformance(
527+
tuple, bitwiseCopyableProtocol)) {
528+
return BitwiseCopyableTypeInfo::create(IGM.OpaqueTy, IsABIAccessible);
529+
}
523530
// FIXME: Figure out if its copyable at least
524531
return &getDynamicTupleTypeInfo(IsCopyable);
525532
}
@@ -696,4 +703,4 @@ llvm::Value *irgen::emitTupleTypeMetadataElementType(IRGenFunction &IGF,
696703

697704
return IGF.Builder.CreateLoad(slot, IGF.IGM.SizeTy,
698705
IGF.IGM.getPointerAlignment());
699-
}
706+
}

lib/IRGen/NonFixedTypeInfo.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "Address.h"
2727
#include "GenOpaque.h"
2828
#include "IndirectTypeInfo.h"
29+
#include "Outlining.h"
2930

3031
namespace swift {
3132
namespace irgen {
@@ -130,6 +131,76 @@ class WitnessSizedTypeInfo : public IndirectTypeInfo<Impl, TypeInfo> {
130131
return nullptr;
131132
}
132133
};
134+
135+
class BitwiseCopyableTypeInfo
136+
: public WitnessSizedTypeInfo<BitwiseCopyableTypeInfo> {
137+
using Self = BitwiseCopyableTypeInfo;
138+
using Super = WitnessSizedTypeInfo<Self>;
139+
BitwiseCopyableTypeInfo(llvm::Type *type, IsABIAccessible_t abiAccessible)
140+
: Super(type, Alignment(1), IsNotTriviallyDestroyable,
141+
IsNotBitwiseTakable, IsCopyable, abiAccessible) {}
142+
143+
public:
144+
static BitwiseCopyableTypeInfo *create(llvm::Type *type,
145+
IsABIAccessible_t abiAccessible) {
146+
return new Self(type, abiAccessible);
147+
}
148+
149+
void bitwiseCopy(IRGenFunction &IGF, Address destAddr, Address srcAddr,
150+
SILType T, bool isOutlined) const {
151+
IGF.Builder.CreateMemCpy(destAddr, srcAddr, getSize(IGF, T));
152+
}
153+
154+
void initializeWithTake(IRGenFunction &IGF, Address destAddr, Address srcAddr,
155+
SILType T, bool isOutlined) const override {
156+
bitwiseCopy(IGF, destAddr, srcAddr, T, isOutlined);
157+
}
158+
159+
void initializeWithCopy(IRGenFunction &IGF, Address destAddr, Address srcAddr,
160+
SILType T, bool isOutlined) const override {
161+
bitwiseCopy(IGF, destAddr, srcAddr, T, isOutlined);
162+
}
163+
164+
void assignWithCopy(IRGenFunction &IGF, Address destAddr, Address srcAddr,
165+
SILType T, bool isOutlined) const override {
166+
bitwiseCopy(IGF, destAddr, srcAddr, T, isOutlined);
167+
}
168+
169+
void assignWithTake(IRGenFunction &IGF, Address destAddr, Address srcAddr,
170+
SILType T, bool isOutlined) const override {
171+
bitwiseCopy(IGF, destAddr, srcAddr, T, isOutlined);
172+
}
173+
174+
void destroy(IRGenFunction &IGF, Address address, SILType T,
175+
bool isOutlined) const override {
176+
// BitwiseCopyable types are trivial, so destroy is a no-op.
177+
}
178+
179+
llvm::Value *getEnumTagSinglePayload(IRGenFunction &IGF,
180+
llvm::Value *numEmptyCases,
181+
Address enumAddr, SILType T,
182+
bool isOutlined) const override {
183+
return emitGetEnumTagSinglePayloadCall(IGF, T, numEmptyCases, enumAddr);
184+
}
185+
186+
void storeEnumTagSinglePayload(IRGenFunction &IGF, llvm::Value *whichCase,
187+
llvm::Value *numEmptyCases, Address enumAddr,
188+
SILType T, bool isOutlined) const override {
189+
emitStoreEnumTagSinglePayloadCall(IGF, T, whichCase, numEmptyCases,
190+
enumAddr);
191+
}
192+
193+
void collectMetadataForOutlining(OutliningMetadataCollector &collector,
194+
SILType T) const override {
195+
// We'll need formal type metadata for this archetype.
196+
collector.collectTypeMetadataForLayout(T);
197+
}
198+
199+
TypeLayoutEntry *buildTypeLayoutEntry(IRGenModule &IGM, SILType T,
200+
bool useStructLayouts) const override {
201+
return IGM.typeLayoutCache.getOrCreateArchetypeEntry(T.getObjectType());
202+
}
203+
};
133204
}
134205
}
135206

0 commit comments

Comments
 (0)