|
20 | 20 | #include "swift/AST/Decl.h"
|
21 | 21 | #include "swift/AST/GenericEnvironment.h"
|
22 | 22 | #include "swift/AST/IRGenOptions.h"
|
| 23 | +#include "swift/AST/KnownProtocols.h" |
23 | 24 | #include "swift/AST/Types.h"
|
24 | 25 | #include "swift/IRGen/Linking.h"
|
25 | 26 | #include "swift/SIL/SILValue.h"
|
@@ -172,6 +173,76 @@ class FixedSizeArchetypeTypeInfo
|
172 | 173 | }
|
173 | 174 | };
|
174 | 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), IsTriviallyDestroyable, IsBitwiseTakable, |
| 183 | + 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 | +}; |
175 | 246 | } // end anonymous namespace
|
176 | 247 |
|
177 | 248 | /// Emit a single protocol witness table reference.
|
@@ -361,6 +432,19 @@ const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {
|
361 | 432 | ? IsABIAccessible
|
362 | 433 | : IsNotABIAccessible;
|
363 | 434 | }
|
| 435 | + |
| 436 | + auto &ASTContext = IGM.getSwiftModule()->getASTContext(); |
| 437 | + if (ASTContext.LangOpts.hasFeature(Feature::BitwiseCopyable)) { |
| 438 | + // TODO: Should this conformance imply isAddressOnlyTrivial is true? |
| 439 | + auto *proto = ASTContext.getProtocol(KnownProtocolKind::BitwiseCopyable); |
| 440 | + // It's possible for the protocol not to exist if the stdlib is built |
| 441 | + // no_asserts. |
| 442 | + if (proto && IGM.getSwiftModule()->lookupConformance(archetype, proto)) { |
| 443 | + return BitwiseCopyableArchetypeTypeInfo::create(storageType, |
| 444 | + abiAccessible); |
| 445 | + } |
| 446 | + } |
| 447 | + |
364 | 448 | return OpaqueArchetypeTypeInfo::create(storageType, abiAccessible);
|
365 | 449 | }
|
366 | 450 |
|
|
0 commit comments