|
13 | 13 | #define DEBUG_TYPE "sil-combine" |
14 | 14 |
|
15 | 15 | #include "SILCombiner.h" |
| 16 | +#include "swift/AST/SemanticAttrs.h" |
16 | 17 | #include "swift/Basic/STLExtras.h" |
| 18 | +#include "swift/SIL/BasicBlockBits.h" |
17 | 19 | #include "swift/SIL/DebugUtils.h" |
18 | 20 | #include "swift/SIL/DynamicCasts.h" |
19 | 21 | #include "swift/SIL/InstructionUtils.h" |
20 | 22 | #include "swift/SIL/PatternMatch.h" |
21 | 23 | #include "swift/SIL/Projection.h" |
22 | | -#include "swift/SIL/BasicBlockBits.h" |
23 | 24 | #include "swift/SIL/SILBuilder.h" |
24 | 25 | #include "swift/SIL/SILInstruction.h" |
25 | 26 | #include "swift/SIL/SILVisitor.h" |
@@ -2148,6 +2149,43 @@ SILInstruction *SILCombiner::visitFixLifetimeInst(FixLifetimeInst *fli) { |
2148 | 2149 | return nullptr; |
2149 | 2150 | } |
2150 | 2151 |
|
| 2152 | +static Optional<SILType> |
| 2153 | +shouldReplaceCallByContiguousArrayStorageAnyObject(SILFunction &F, |
| 2154 | + CanType storageMetaTy) { |
| 2155 | + auto metaTy = dyn_cast<MetatypeType>(storageMetaTy); |
| 2156 | + if (!metaTy || metaTy->getRepresentation() != MetatypeRepresentation::Thick) |
| 2157 | + return None; |
| 2158 | + |
| 2159 | + auto storageTy = metaTy.getInstanceType()->getCanonicalType(); |
| 2160 | + if (!storageTy->is_ContiguousArrayStorage()) |
| 2161 | + return None; |
| 2162 | + |
| 2163 | + auto boundGenericTy = dyn_cast<BoundGenericType>(storageTy); |
| 2164 | + if (!boundGenericTy) |
| 2165 | + return None; |
| 2166 | + |
| 2167 | + // On SwiftStdlib 5.7 we can replace the call. |
| 2168 | + auto &ctxt = storageMetaTy->getASTContext(); |
| 2169 | + auto deployment = AvailabilityContext::forDeploymentTarget(ctxt); |
| 2170 | + if (!deployment.isContainedIn(ctxt.getSwift57Availability())) |
| 2171 | + return None; |
| 2172 | + |
| 2173 | + auto genericArgs = boundGenericTy->getGenericArgs(); |
| 2174 | + if (genericArgs.size() != 1) |
| 2175 | + return None; |
| 2176 | + |
| 2177 | + auto ty = genericArgs[0]->getCanonicalType(); |
| 2178 | + if (!ty->getClassOrBoundGenericClass() && !ty->isObjCExistentialType()) |
| 2179 | + return None; |
| 2180 | + |
| 2181 | + auto anyObjectTy = ctxt.getAnyObjectType(); |
| 2182 | + auto arrayStorageTy = |
| 2183 | + BoundGenericClassType::get(ctxt.get_ContiguousArrayStorageDecl(), nullptr, |
| 2184 | + {anyObjectTy}) |
| 2185 | + ->getCanonicalType(); |
| 2186 | + return F.getTypeLowering(arrayStorageTy).getLoweredType(); |
| 2187 | +} |
| 2188 | + |
2151 | 2189 | SILInstruction * |
2152 | 2190 | SILCombiner:: |
2153 | 2191 | visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) { |
@@ -2209,6 +2247,32 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) { |
2209 | 2247 | ARDI->getTailAllocatedTypes(), |
2210 | 2248 | getCounts(ARDI)); |
2211 | 2249 | } |
| 2250 | + } else if (auto *AI = dyn_cast<ApplyInst>(MDVal)) { |
| 2251 | + SILFunction *SF = AI->getReferencedFunctionOrNull(); |
| 2252 | + if (!SF) |
| 2253 | + return nullptr; |
| 2254 | + |
| 2255 | + if (!SF->hasSemanticsAttr(semantics::ARRAY_GET_CONTIGUOUSARRAYSTORAGETYPE)) |
| 2256 | + return nullptr; |
| 2257 | + |
| 2258 | + auto use = AI->getSingleUse(); |
| 2259 | + if (!use || use->getUser() != ARDI) |
| 2260 | + return nullptr; |
| 2261 | + |
| 2262 | + auto silTy = AI->getType(); |
| 2263 | + auto storageTy = AI->getType().getASTType(); |
| 2264 | + // getContiguousArrayStorageType<SomeClass> => |
| 2265 | + // ContiguousArrayStorage<AnyObject> |
| 2266 | + auto instanceTy = shouldReplaceCallByContiguousArrayStorageAnyObject( |
| 2267 | + *AI->getFunction(), storageTy); |
| 2268 | + if (!instanceTy) |
| 2269 | + return nullptr; |
| 2270 | + NewInst = Builder.createAllocRef( |
| 2271 | + ARDI->getLoc(), *instanceTy, ARDI->isObjC(), false, |
| 2272 | + ARDI->getTailAllocatedTypes(), getCounts(ARDI)); |
| 2273 | + NewInst = Builder.createUncheckedRefCast(ARDI->getLoc(), NewInst, |
| 2274 | + ARDI->getType()); |
| 2275 | + return NewInst; |
2212 | 2276 | } |
2213 | 2277 | if (NewInst && NewInst->getType() != ARDI->getType()) { |
2214 | 2278 | // In case the argument was an upcast of the metatype, we have to upcast the |
|
0 commit comments