@@ -81,6 +81,10 @@ class LargeSILTypeMapper {
81
81
ArrayRef<SILResultInfo> origResults,
82
82
irgen::IRGenModule &Mod);
83
83
bool shouldConvertBBArg (SILArgument *arg, irgen::IRGenModule &Mod);
84
+ bool containsDifferentFunctionSignature (GenericEnvironment *genEnv,
85
+ irgen::IRGenModule &Mod,
86
+ SILType storageType,
87
+ SILType newSILType);
84
88
85
89
private:
86
90
// Cache of already computed type transforms
@@ -153,20 +157,44 @@ bool LargeSILTypeMapper::shouldTransformFunctionType(GenericEnvironment *env,
153
157
return false ;
154
158
}
155
159
156
- static bool containsFunctionSignature (GenericEnvironment *genEnv,
157
- irgen::IRGenModule &Mod,
158
- SILType storageType, SILType newSILType) {
159
- if (!isLargeLoadableType (genEnv, storageType, Mod) &&
160
- (newSILType != storageType)) {
160
+ // Get the function type or the optional function type
161
+ static CanSILFunctionType getInnerFunctionType (SILType storageType) {
162
+ if (auto currSILFunctionType = storageType.getAs <SILFunctionType>()) {
163
+ return currSILFunctionType;
164
+ }
165
+ if (auto optionalType = storageType.getOptionalObjectType ()) {
166
+ if (auto currSILFunctionType = optionalType.getAs <SILFunctionType>()) {
167
+ return currSILFunctionType;
168
+ }
169
+ }
170
+ return CanSILFunctionType ();
171
+ }
172
+
173
+ static SILType getNonOptionalType (SILType t) {
174
+ SILType nonOptionalType = t;
175
+ if (auto optType = t.getOptionalObjectType ()) {
176
+ nonOptionalType = optType;
177
+ }
178
+ return nonOptionalType;
179
+ }
180
+
181
+ bool LargeSILTypeMapper::containsDifferentFunctionSignature (
182
+ GenericEnvironment *genEnv, irgen::IRGenModule &Mod, SILType storageType,
183
+ SILType newSILType) {
184
+ if (storageType == newSILType) {
185
+ return false ;
186
+ }
187
+ if (getInnerFunctionType (storageType)) {
161
188
return true ;
162
189
}
163
- if (auto origType = storageType.getAs <TupleType>()) {
164
- for (auto canElem : origType.getElementTypes ()) {
165
- SILType objectType = SILType::getPrimitiveObjectType (canElem);
166
- if (auto optionalObject = objectType.getOptionalObjectType ()) {
167
- objectType = optionalObject;
168
- }
169
- if (objectType.is <SILFunctionType>()) {
190
+ SILType nonOptionalType = getNonOptionalType (storageType);
191
+ if (nonOptionalType.getAs <TupleType>()) {
192
+ auto origType = nonOptionalType.getAs <TupleType>();
193
+ for (TupleTypeElt canElem : origType->getElements ()) {
194
+ auto origCanType = CanType (canElem.getRawType ());
195
+ auto elem = SILType::getPrimitiveObjectType (origCanType);
196
+ auto newElem = getNewSILType (genEnv, elem, Mod);
197
+ if (containsDifferentFunctionSignature (genEnv, Mod, elem, newElem)) {
170
198
return true ;
171
199
}
172
200
}
@@ -182,7 +210,8 @@ bool LargeSILTypeMapper::newResultsDiffer(GenericEnvironment *GenericEnv,
182
210
SILType currResultTy = result.getSILStorageType ();
183
211
SILType newSILType = getNewSILType (GenericEnv, currResultTy, Mod);
184
212
// We (currently) only care about function signatures
185
- if (containsFunctionSignature (GenericEnv, Mod, currResultTy, newSILType)) {
213
+ if (containsDifferentFunctionSignature (GenericEnv, Mod, currResultTy,
214
+ newSILType)) {
186
215
return true ;
187
216
}
188
217
}
@@ -218,16 +247,16 @@ LargeSILTypeMapper::getNewResults(GenericEnvironment *GenericEnv,
218
247
for (auto result : origResults) {
219
248
SILType currResultTy = result.getSILStorageType ();
220
249
SILType newSILType = getNewSILType (GenericEnv, currResultTy, Mod);
221
- // We (currently) only care about function signatures
222
- if (containsFunctionSignature (GenericEnv, Mod, currResultTy, newSILType)) {
223
- // Case (1) Above
224
- SILResultInfo newResult (newSILType.getASTType (), result.getConvention ());
225
- newResults.push_back (newResult);
226
- } else if (modNonFuncTypeResultType (GenericEnv, fnType, Mod)) {
250
+ if (modNonFuncTypeResultType (GenericEnv, fnType, Mod)) {
227
251
// Case (2) Above
228
252
SILResultInfo newSILResultInfo (newSILType.getASTType (),
229
253
ResultConvention::Indirect);
230
254
newResults.push_back (newSILResultInfo);
255
+ } else if (containsDifferentFunctionSignature (GenericEnv, Mod, currResultTy,
256
+ newSILType)) {
257
+ // Case (1) Above
258
+ SILResultInfo newResult (newSILType.getASTType (), result.getConvention ());
259
+ newResults.push_back (newResult);
231
260
} else {
232
261
newResults.push_back (result);
233
262
}
@@ -259,19 +288,6 @@ LargeSILTypeMapper::getNewSILFunctionType(GenericEnvironment *env,
259
288
return newFnType;
260
289
}
261
290
262
- // Get the function type or the optional function type
263
- static CanSILFunctionType getInnerFunctionType (SILType storageType) {
264
- if (auto currSILFunctionType = storageType.getAs <SILFunctionType>()) {
265
- return currSILFunctionType;
266
- }
267
- if (auto optionalType = storageType.getOptionalObjectType ()) {
268
- if (auto currSILFunctionType = optionalType.getAs <SILFunctionType>()) {
269
- return currSILFunctionType;
270
- }
271
- }
272
- return CanSILFunctionType ();
273
- }
274
-
275
291
SILType
276
292
LargeSILTypeMapper::getNewOptionalFunctionType (GenericEnvironment *GenericEnv,
277
293
SILType storageType,
@@ -540,6 +556,11 @@ struct StructLoweringState {
540
556
return Mapper.getNewSILType (F->getGenericEnvironment (), type, Mod);
541
557
}
542
558
559
+ bool containsDifferentFunctionSignature (SILType type) {
560
+ return Mapper.containsDifferentFunctionSignature (
561
+ F->getGenericEnvironment (), Mod, type, getNewSILType (type));
562
+ }
563
+
543
564
bool hasLargeLoadableYields () {
544
565
auto fnType = F->getLoweredFunctionType ();
545
566
if (!fnType->isCoroutine ()) return false ;
@@ -819,7 +840,8 @@ bool LargeSILTypeMapper::shouldConvertBBArg(SILArgument *arg,
819
840
}
820
841
SILType newSILType = getNewSILType (genEnv, storageType, Mod);
821
842
// We (currently) only care about function signatures
822
- if (containsFunctionSignature (genEnv, Mod, storageType, newSILType)) {
843
+ if (containsDifferentFunctionSignature (genEnv, Mod, storageType,
844
+ newSILType)) {
823
845
return true ;
824
846
}
825
847
return false ;
@@ -1347,15 +1369,16 @@ void LoadableStorageAllocation::insertIndirectReturnArgs() {
1347
1369
canType = genEnv->mapTypeIntoContext (canType)->getCanonicalType ();
1348
1370
}
1349
1371
resultStorageType = SILType::getPrimitiveObjectType (canType);
1372
+ auto newResultStorageType = pass.getNewSILType (resultStorageType);
1350
1373
1351
1374
auto &ctx = pass.F ->getModule ().getASTContext ();
1352
1375
auto var = new (ctx) ParamDecl (
1353
1376
VarDecl::Specifier::InOut, SourceLoc (), SourceLoc (),
1354
1377
ctx.getIdentifier (" $return_value" ), SourceLoc (),
1355
1378
ctx.getIdentifier (" $return_value" ),
1356
1379
pass.F ->getDeclContext ());
1357
- pass.F ->begin ()->insertFunctionArgument (0 , resultStorageType. getAddressType (),
1358
- ValueOwnershipKind::Any, var);
1380
+ pass.F ->begin ()->insertFunctionArgument (
1381
+ 0 , newResultStorageType. getAddressType (), ValueOwnershipKind::Any, var);
1359
1382
}
1360
1383
1361
1384
void LoadableStorageAllocation::convertIndirectFunctionArgs () {
@@ -1467,9 +1490,8 @@ void LoadableStorageAllocation::
1467
1490
1468
1491
for (SILArgument *arg : entry->getArguments ()) {
1469
1492
SILType storageType = arg->getType ();
1470
- GenericEnvironment *genEnv = pass.F ->getGenericEnvironment ();
1471
1493
SILType newSILType = pass.getNewSILType (storageType);
1472
- if (containsFunctionSignature (genEnv, pass.Mod , storageType, newSILType )) {
1494
+ if (pass.containsDifferentFunctionSignature ( storageType)) {
1473
1495
auto *castInstr = argBuilder.createUncheckedBitCast (
1474
1496
RegularLocation (const_cast <ValueDecl *>(arg->getDecl ())), arg,
1475
1497
newSILType);
@@ -1493,6 +1515,12 @@ void LoadableStorageAllocation::convertIndirectBasicBlockArgs() {
1493
1515
}
1494
1516
SILType storageType = arg->getType ();
1495
1517
SILType newSILType = pass.getNewSILType (storageType);
1518
+ // We don't change the type from object to address for function args:
1519
+ // a tuple with both a large type and a function arg should remain
1520
+ // as an object type for now
1521
+ if (storageType.isObject ()) {
1522
+ newSILType = newSILType.getObjectType ();
1523
+ }
1496
1524
convertBBArgType (argBuilder, newSILType, arg);
1497
1525
}
1498
1526
}
@@ -2238,18 +2266,14 @@ static void rewriteFunction(StructLoweringState &pass,
2238
2266
// If it is a large type also return true - will be re-written later
2239
2267
// Returns true if the return argument needed re-writing
2240
2268
static bool rewriteFunctionReturn (StructLoweringState &pass) {
2241
- GenericEnvironment *genEnv = pass.F ->getGenericEnvironment ();
2242
2269
auto loweredTy = pass.F ->getLoweredFunctionType ();
2243
2270
SILFunction *F = pass.F ;
2244
2271
SILType resultTy = loweredTy->getAllResultsType ();
2245
2272
SILType newSILType = pass.getNewSILType (resultTy);
2246
2273
// We (currently) only care about function signatures
2247
2274
if (pass.isLargeLoadableType (resultTy)) {
2248
2275
return true ;
2249
- } else if (containsFunctionSignature (genEnv, pass.Mod , resultTy,
2250
- newSILType) &&
2251
- (resultTy != newSILType)) {
2252
-
2276
+ } else if (pass.containsDifferentFunctionSignature (resultTy)) {
2253
2277
llvm::SmallVector<SILResultInfo, 2 > newSILResultInfo;
2254
2278
if (auto tupleType = newSILType.getAs <TupleType>()) {
2255
2279
auto originalResults = loweredTy->getResults ();
0 commit comments