@@ -211,12 +211,64 @@ static SILType getNewSILFunctionType(GenericEnvironment *GenericEnv,
211
211
return newSILType;
212
212
}
213
213
214
+ // Get the funciton type or the optional function type
215
+ static SILFunctionType *getInnerFunctionType (SILType storageType) {
216
+ CanType currCanType = storageType.getSwiftRValueType ();
217
+ if (SILFunctionType *currSILFunctionType =
218
+ dyn_cast<SILFunctionType>(currCanType.getPointer ())) {
219
+ return currSILFunctionType;
220
+ }
221
+ OptionalTypeKind optKind;
222
+ if (auto optionalType = currCanType.getAnyOptionalObjectType (optKind)) {
223
+ assert (optKind != OptionalTypeKind::OTK_None &&
224
+ " Expected Real Optional Type" );
225
+ if (auto *currSILFunctionType =
226
+ dyn_cast<SILFunctionType>(optionalType.getPointer ())) {
227
+ return currSILFunctionType;
228
+ }
229
+ }
230
+ return nullptr ;
231
+ }
232
+
233
+ static SILType getNewOptionalFunctionType (GenericEnvironment *GenericEnv,
234
+ SILType storageType,
235
+ irgen::IRGenModule &Mod) {
236
+ SILType newSILType = storageType;
237
+ CanType currCanType = storageType.getSwiftRValueType ();
238
+ OptionalTypeKind optKind;
239
+ if (auto optionalType = currCanType.getAnyOptionalObjectType (optKind)) {
240
+ assert (optKind != OptionalTypeKind::OTK_None &&
241
+ " Expected Real Optional Type" );
242
+ if (auto *currSILFunctionType =
243
+ dyn_cast<SILFunctionType>(optionalType.getPointer ())) {
244
+ if (containsLargeLoadable (GenericEnv,
245
+ currSILFunctionType->getParameters (), Mod)) {
246
+ newSILType =
247
+ getNewSILFunctionType (GenericEnv, currSILFunctionType, Mod);
248
+ currCanType = newSILType.getSwiftRValueType ();
249
+ auto newType = OptionalType::get (optKind, currCanType);
250
+ CanType newCanType = newType->getCanonicalType ();
251
+ newSILType = SILType::getPrimitiveObjectType (newCanType);
252
+ }
253
+ }
254
+ }
255
+ return newSILType;
256
+ }
257
+
214
258
static SmallVector<SILParameterInfo, 4 >
215
259
getNewArgTys (GenericEnvironment *GenericEnv, ArrayRef<SILParameterInfo> params,
216
260
irgen::IRGenModule &Mod) {
217
261
SmallVector<SILParameterInfo, 4 > newArgTys;
218
262
for (SILParameterInfo param : params) {
219
263
SILType storageType = param.getSILStorageType ();
264
+ SILType newOptFuncType =
265
+ getNewOptionalFunctionType (GenericEnv, storageType, Mod);
266
+ if (newOptFuncType != storageType) {
267
+ auto newParam = SILParameterInfo (newOptFuncType.getSwiftRValueType (),
268
+ param.getConvention ());
269
+ newArgTys.push_back (newParam);
270
+ continue ;
271
+ }
220
272
CanType currCanType = storageType.getSwiftRValueType ();
221
273
if (SILFunctionType *currSILFunctionType =
222
274
dyn_cast<SILFunctionType>(currCanType.getPointer ())) {
@@ -245,26 +297,11 @@ getNewArgTys(GenericEnvironment *GenericEnv, ArrayRef<SILParameterInfo> params,
245
297
246
298
static SILType getNewSILType (GenericEnvironment *GenericEnv,
247
299
SILType storageType, irgen::IRGenModule &Mod) {
248
- SILType newSILType = storageType;
249
- CanType currCanType = storageType.getSwiftRValueType ();
250
- OptionalTypeKind optKind;
251
- if (auto optionalType = currCanType.getAnyOptionalObjectType (optKind)) {
252
- assert (optKind != OptionalTypeKind::OTK_None &&
253
- " Expected Real Optional Type" );
254
- if (SILFunctionType *currSILFunctionType =
255
- dyn_cast<SILFunctionType>(optionalType.getPointer ())) {
256
- if (containsLargeLoadable (GenericEnv,
257
- currSILFunctionType->getParameters (), Mod)) {
258
- newSILType =
259
- getNewSILFunctionType (GenericEnv, currSILFunctionType, Mod);
260
- currCanType = newSILType.getSwiftRValueType ();
261
- auto newType = OptionalType::get (optKind, currCanType);
262
- CanType newCanType = newType->getCanonicalType ();
263
- newSILType = SILType::getPrimitiveObjectType (newCanType);
264
- return newSILType;
265
- }
266
- }
300
+ SILType newSILType = getNewOptionalFunctionType (GenericEnv, storageType, Mod);
301
+ if (newSILType != storageType) {
302
+ return newSILType;
267
303
}
304
+ CanType currCanType = storageType.getSwiftRValueType ();
268
305
if (auto *currSILBlockType =
269
306
dyn_cast<SILBlockStorageType>(currCanType.getPointer ())) {
270
307
return storageType;
@@ -309,6 +346,10 @@ struct StructLoweringState {
309
346
SmallVector<StructExtractInst *, 16 > structExtractInstsToMod;
310
347
// All tuple instructions for which the return type is a function type
311
348
SmallVector<SILInstruction *, 8 > tupleInstsToMod;
349
+ // All allock stack instructions to modify
350
+ SmallVector<AllocStackInst *, 8 > allocStackInstsToMod;
351
+ // All pointer to address instructions to modify
352
+ SmallVector<PointerToAddressInst *, 8 > pointerToAddrkInstsToMod;
312
353
// All Retain and release instrs should be replaced with _addr version
313
354
SmallVector<RetainValueInst *, 16 > retainInstsToMod;
314
355
SmallVector<ReleaseValueInst *, 16 > releaseInstsToMod;
@@ -353,6 +394,8 @@ class LargeValueVisitor {
353
394
void visitResultTyInst (SILInstruction *instr);
354
395
void visitDebugValueInst (DebugValueInst *instr);
355
396
void visitTupleInst (SILInstruction *instr);
397
+ void visitAllocStackInst (AllocStackInst *instr);
398
+ void visitPointerToAddressInst (PointerToAddressInst *instr);
356
399
void visitInstr (SILInstruction *instr);
357
400
};
358
401
} // end anonymous namespace
@@ -419,6 +462,16 @@ void LargeValueVisitor::mapValueStorage() {
419
462
visitTupleInst (currIns);
420
463
break ;
421
464
}
465
+ case ValueKind::AllocStackInst: {
466
+ auto *ASI = dyn_cast<AllocStackInst>(currIns);
467
+ visitAllocStackInst (ASI);
468
+ break ;
469
+ }
470
+ case ValueKind::PointerToAddressInst: {
471
+ auto *PTA = dyn_cast<PointerToAddressInst>(currIns);
472
+ visitPointerToAddressInst (PTA);
473
+ break ;
474
+ }
422
475
default : {
423
476
assert (!ApplySite::isa (currIns) && " Did not expect an ApplySite" );
424
477
assert (!dyn_cast<MethodInst>(currIns) && " Unhandled Method Inst" );
@@ -633,6 +686,20 @@ void LargeValueVisitor::visitTupleInst(SILInstruction *instr) {
633
686
visitInstr (instr);
634
687
}
635
688
689
+ void LargeValueVisitor::visitAllocStackInst (AllocStackInst *instr) {
690
+ SILType currSILType = instr->getType ().getObjectType ();
691
+ if (auto *fType = getInnerFunctionType (currSILType)) {
692
+ pass.allocStackInstsToMod .push_back (instr);
693
+ }
694
+ }
695
+
696
+ void LargeValueVisitor::visitPointerToAddressInst (PointerToAddressInst *instr) {
697
+ SILType currSILType = instr->getType ().getObjectType ();
698
+ if (auto *fType = getInnerFunctionType (currSILType)) {
699
+ pass.pointerToAddrkInstsToMod .push_back (instr);
700
+ }
701
+ }
702
+
636
703
void LargeValueVisitor::visitInstr (SILInstruction *instr) {
637
704
for (Operand &operand : instr->getAllOperands ()) {
638
705
if (std::find (pass.largeLoadableArgs .begin (), pass.largeLoadableArgs .end (),
@@ -1080,13 +1147,16 @@ class LoadableByAddress : public SILModuleTransform {
1080
1147
void recreateConvInstrs ();
1081
1148
void recreateLoadInstrs ();
1082
1149
void recreateUncheckedEnumDataInstrs ();
1150
+ void recreateUncheckedTakeEnumDataAddrInst ();
1083
1151
void fixStoreToBlockStorageInstrs ();
1084
1152
1085
1153
private:
1086
1154
llvm::SetVector<SILFunction *> modFuncs;
1087
1155
llvm::SetVector<SILInstruction *> conversionInstrs;
1088
1156
llvm::SetVector<LoadInst *> loadInstrsOfFunc;
1089
1157
llvm::SetVector<UncheckedEnumDataInst *> uncheckedEnumDataOfFunc;
1158
+ llvm::SetVector<UncheckedTakeEnumDataAddrInst *>
1159
+ uncheckedTakeEnumDataAddrOfFunc;
1090
1160
llvm::SetVector<StoreInst *> storeToBlockStorageInstrs;
1091
1161
llvm::DenseSet<SILInstruction *> modApplies;
1092
1162
};
@@ -1414,6 +1484,28 @@ static void rewriteFunction(StructLoweringState &pass,
1414
1484
castTupleInstr (instr, pass.Mod );
1415
1485
}
1416
1486
1487
+ while (!pass.allocStackInstsToMod .empty ()) {
1488
+ auto *instr = pass.allocStackInstsToMod .pop_back_val ();
1489
+ SILBuilder allocBuilder (instr);
1490
+ SILType currSILType = instr->getType ();
1491
+ SILType newSILType = getNewSILType (genEnv, currSILType, pass.Mod );
1492
+ auto *newInstr = allocBuilder.createAllocStack (instr->getLoc (), newSILType);
1493
+ instr->replaceAllUsesWith (newInstr);
1494
+ instr->getParent ()->erase (instr);
1495
+ }
1496
+
1497
+ while (!pass.pointerToAddrkInstsToMod .empty ()) {
1498
+ auto *instr = pass.pointerToAddrkInstsToMod .pop_back_val ();
1499
+ SILBuilder pointerBuilder (instr);
1500
+ SILType currSILType = instr->getType ();
1501
+ SILType newSILType = getNewSILType (genEnv, currSILType, pass.Mod );
1502
+ auto *newInstr = pointerBuilder.createPointerToAddress (
1503
+ instr->getLoc (), instr->getOperand (), newSILType.getAddressType (),
1504
+ instr->isStrict ());
1505
+ instr->replaceAllUsesWith (newInstr);
1506
+ instr->getParent ()->erase (instr);
1507
+ }
1508
+
1417
1509
for (SILInstruction *instr : pass.debugInstsToMod ) {
1418
1510
assert (instr->getAllOperands ().size () == 1 &&
1419
1511
" Debug instructions have one operand" );
@@ -1583,37 +1675,21 @@ static bool rewriteFunctionReturn(StructLoweringState &pass) {
1583
1675
}
1584
1676
SILFunction *F = pass.F ;
1585
1677
SILType resultTy = loweredTy->getAllResultsType ();
1586
- CanType resultCanTy = resultTy.getSwiftRValueType ();
1587
- if (SILFunctionType *currSILFunctionType =
1588
- dyn_cast<SILFunctionType>(resultCanTy.getPointer ())) {
1589
- if (containsLargeLoadable (genEnv, currSILFunctionType->getParameters (),
1590
- pass.Mod )) {
1591
- assert (F->getLoweredFunctionType ()->getNumResults () == 1 &&
1592
- " Expected a single result" );
1593
- SILResultInfo origResultInfo = loweredTy->getSingleResult ();
1594
- SmallVector<SILParameterInfo, 4 > newArgTys =
1595
- getNewArgTys (genEnv, currSILFunctionType->getParameters (), pass.Mod );
1596
- SILFunctionType *newSILFunctionType =
1597
- SILFunctionType::get (currSILFunctionType->getGenericSignature (),
1598
- currSILFunctionType->getExtInfo (),
1599
- currSILFunctionType->getCalleeConvention (),
1600
- newArgTys, currSILFunctionType->getResults (),
1601
- currSILFunctionType->getOptionalErrorResult (),
1602
- currSILFunctionType->getASTContext ());
1603
- SILType newSILType = SILType::getPrimitiveObjectType (
1604
- newSILFunctionType->getCanonicalType ());
1605
- SILResultInfo newSILResultInfo (newSILType.getSwiftRValueType (),
1606
- origResultInfo.getConvention ());
1607
- // change the caller's SIL function type
1608
- SILFunctionType *OrigFTI = F->getLoweredFunctionType ();
1609
- auto NewTy = SILFunctionType::get (
1610
- OrigFTI->getGenericSignature (), OrigFTI->getExtInfo (),
1611
- OrigFTI->getCalleeConvention (), OrigFTI->getParameters (),
1612
- newSILResultInfo, OrigFTI->getOptionalErrorResult (),
1613
- F->getModule ().getASTContext ());
1614
- F->rewriteLoweredTypeUnsafe (NewTy);
1615
- return true ;
1616
- }
1678
+ SILType newSILType = getNewSILType (genEnv, resultTy, pass.Mod );
1679
+ // We (currently) only care about function signatures
1680
+ if (!isLargeLoadableType (genEnv, resultTy, pass.Mod ) &&
1681
+ (newSILType != resultTy)) {
1682
+ assert (loweredTy->getNumResults () == 1 && " Expected a single result" );
1683
+ SILResultInfo origResultInfo = loweredTy->getSingleResult ();
1684
+ SILResultInfo newSILResultInfo (newSILType.getSwiftRValueType (),
1685
+ origResultInfo.getConvention ());
1686
+ auto NewTy = SILFunctionType::get (
1687
+ loweredTy->getGenericSignature (), loweredTy->getExtInfo (),
1688
+ loweredTy->getCalleeConvention (), loweredTy->getParameters (),
1689
+ newSILResultInfo, loweredTy->getOptionalErrorResult (),
1690
+ F->getModule ().getASTContext ());
1691
+ F->rewriteLoweredTypeUnsafe (NewTy);
1692
+ return true ;
1617
1693
}
1618
1694
return false ;
1619
1695
}
@@ -1796,6 +1872,29 @@ void LoadableByAddress::recreateUncheckedEnumDataInstrs() {
1796
1872
}
1797
1873
}
1798
1874
1875
+ void LoadableByAddress::recreateUncheckedTakeEnumDataAddrInst () {
1876
+ for (auto *enumInstr : uncheckedTakeEnumDataAddrOfFunc) {
1877
+ SILBuilder enumBuilder (enumInstr);
1878
+ SILFunction *F = enumInstr->getFunction ();
1879
+ CanSILFunctionType funcType = F->getLoweredFunctionType ();
1880
+ IRGenModule *currIRMod = getIRGenModule ()->IRGen .getGenModule (F);
1881
+ Lowering::GenericContextScope GenericScope (getModule ()->Types ,
1882
+ funcType->getGenericSignature ());
1883
+ SILType origType = enumInstr->getType ();
1884
+ GenericEnvironment *genEnv = F->getGenericEnvironment ();
1885
+ auto loweredTy = F->getLoweredFunctionType ();
1886
+ if (!genEnv && loweredTy->isPolymorphic ()) {
1887
+ genEnv = getGenericEnvironment (F->getModule (), loweredTy);
1888
+ }
1889
+ SILType newType = getNewSILType (genEnv, origType, *currIRMod);
1890
+ auto *newInstr = enumBuilder.createUncheckedTakeEnumDataAddr (
1891
+ enumInstr->getLoc (), enumInstr->getOperand (), enumInstr->getElement (),
1892
+ newType.getAddressType ());
1893
+ enumInstr->replaceAllUsesWith (newInstr);
1894
+ enumInstr->getParent ()->erase (enumInstr);
1895
+ }
1896
+ }
1897
+
1799
1898
void LoadableByAddress::fixStoreToBlockStorageInstrs () {
1800
1899
for (auto *instr : storeToBlockStorageInstrs) {
1801
1900
auto dest = instr->getDest ();
@@ -1934,24 +2033,28 @@ void LoadableByAddress::run() {
1934
2033
}
1935
2034
} else if (auto *LI = dyn_cast<LoadInst>(&I)) {
1936
2035
SILType currType = LI->getType ();
1937
- CanType currCanType = currType.getSwiftRValueType ();
1938
- if (auto *fType =
1939
- dyn_cast<SILFunctionType>(currCanType.getPointer ())) {
2036
+ if (auto *fType = getInnerFunctionType (currType)) {
1940
2037
if (modifiableFunction (CanSILFunctionType (fType ))) {
1941
2038
// need to re-create these loads: re-write type cache
1942
2039
loadInstrsOfFunc.insert (LI);
1943
2040
}
1944
2041
}
1945
2042
} else if (auto *UED = dyn_cast<UncheckedEnumDataInst>(&I)) {
1946
2043
SILType currType = UED->getType ();
1947
- CanType currCanType = currType.getSwiftRValueType ();
1948
- if (auto *fType =
1949
- dyn_cast<SILFunctionType>(currCanType.getPointer ())) {
2044
+ if (auto *fType = getInnerFunctionType (currType)) {
1950
2045
if (modifiableFunction (CanSILFunctionType (fType ))) {
1951
2046
// need to re-create these loads: re-write type cache
1952
2047
uncheckedEnumDataOfFunc.insert (UED);
1953
2048
}
1954
2049
}
2050
+ } else if (auto *UED = dyn_cast<UncheckedTakeEnumDataAddrInst>(&I)) {
2051
+ SILType currType = UED->getType ();
2052
+ if (auto *fType = getInnerFunctionType (currType)) {
2053
+ if (modifiableFunction (CanSILFunctionType (fType ))) {
2054
+ // need to re-create these loads: re-write type cache
2055
+ uncheckedTakeEnumDataAddrOfFunc.insert (UED);
2056
+ }
2057
+ }
1955
2058
} else if (auto *SI = dyn_cast<StoreInst>(&I)) {
1956
2059
auto dest = SI->getDest ();
1957
2060
if (isa<ProjectBlockStorageInst>(dest)) {
@@ -1983,12 +2086,15 @@ void LoadableByAddress::run() {
1983
2086
// Re-create all conversions for which we modified the FunctionRef
1984
2087
recreateConvInstrs ();
1985
2088
1986
- // Re-create all load instrs of function pointers
1987
- recreateLoadInstrs ();
1988
-
1989
2089
// Re-create all unchecked enum data instrs of function pointers
1990
2090
recreateUncheckedEnumDataInstrs ();
1991
2091
2092
+ // Same for data addr
2093
+ recreateUncheckedTakeEnumDataAddrInst ();
2094
+
2095
+ // Re-create all load instrs of function pointers
2096
+ recreateLoadInstrs ();
2097
+
1992
2098
// Re-create all applies that we modified in the module
1993
2099
recreateApplies ();
1994
2100
0 commit comments