Skip to content

Commit 77c160c

Browse files
author
Joe Shajrawi
authored
Merge pull request #17545 from dingobye/sr8076
[IRGen] Handle tuple return types with function signature for LoadableByAddress transformation.
2 parents 131b860 + 3b377eb commit 77c160c

File tree

2 files changed

+121
-19
lines changed

2 files changed

+121
-19
lines changed

lib/IRGen/LoadableByAddress.cpp

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,13 @@ bool LargeSILTypeMapper::shouldTransformResults(GenericEnvironment *genEnv,
296296
if (!modifiableFunction(loweredTy)) {
297297
return false;
298298
}
299+
299300
if (loweredTy->getNumResults() != 1) {
300-
return false;
301+
auto resultType = loweredTy->getAllResultsType();
302+
auto newResultType = getNewSILType(genEnv, resultType, Mod);
303+
return resultType != newResultType;
301304
}
305+
302306
auto singleResult = loweredTy->getSingleResult();
303307
auto resultStorageType = singleResult.getSILStorageType();
304308
auto newResultStorageType = getNewSILType(genEnv, resultStorageType, Mod);
@@ -452,6 +456,7 @@ SILType LargeSILTypeMapper::getNewSILType(GenericEnvironment *GenericEnv,
452456
}
453457
SILType newSILType = getNewOptionalFunctionType(GenericEnv, storageType, Mod);
454458
if (newSILType != storageType) {
459+
oldToNewTypeMap[typePair] = newSILType;
455460
return newSILType;
456461
}
457462
if (auto fnType = storageType.getAs<SILFunctionType>()) {
@@ -1286,8 +1291,7 @@ SILArgument *LoadableStorageAllocation::replaceArgType(SILBuilder &argBuilder,
12861291
void LoadableStorageAllocation::insertIndirectReturnArgs() {
12871292
GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
12881293
auto loweredTy = pass.F->getLoweredFunctionType();
1289-
auto singleResult = loweredTy->getSingleResult();
1290-
SILType resultStorageType = singleResult.getSILStorageType();
1294+
SILType resultStorageType = loweredTy->getAllResultsType();
12911295
auto canType = resultStorageType.getASTType();
12921296
if (canType->hasTypeParameter()) {
12931297
assert(genEnv && "Expected a GenericEnv");
@@ -1367,19 +1371,26 @@ void LoadableStorageAllocation::convertApplyResults() {
13671371
pass.Mod)) {
13681372
continue;
13691373
}
1370-
auto singleResult = origSILFunctionType->getSingleResult();
1371-
auto resultStorageType = singleResult.getSILStorageType();
1374+
auto resultStorageType = origSILFunctionType->getAllResultsType();
13721375
if (!isLargeLoadableType(genEnv, resultStorageType, pass.Mod)) {
1373-
// Make sure it is a function type
1374-
if (!resultStorageType.is<SILFunctionType>()) {
1375-
// Check if it is an optional function type
1376-
auto optionalType = resultStorageType.getOptionalObjectType();
1377-
assert(optionalType &&
1378-
"Expected SILFunctionType or Optional for the result type");
1379-
assert(optionalType.is<SILFunctionType>() &&
1380-
"Expected a SILFunctionType inside the optional Type");
1381-
(void)optionalType;
1382-
}
1376+
// Make sure it contains a function type
1377+
auto numFuncTy = llvm::count_if(origSILFunctionType->getResults(),
1378+
[](const SILResultInfo &origResult) {
1379+
auto resultStorageTy = origResult.getSILStorageType();
1380+
// Check if it is a function type
1381+
if (resultStorageTy.is<SILFunctionType>()) {
1382+
return true;
1383+
}
1384+
// Check if it is an optional function type
1385+
auto optionalType = resultStorageTy.getOptionalObjectType();
1386+
if (optionalType && optionalType.is<SILFunctionType>()) {
1387+
return true;
1388+
}
1389+
return false;
1390+
});
1391+
assert(numFuncTy != 0 &&
1392+
"Expected a SILFunctionType inside the result Type");
1393+
(void)numFuncTy;
13831394
continue;
13841395
}
13851396
auto newSILType =
@@ -2213,10 +2224,24 @@ static bool rewriteFunctionReturn(StructLoweringState &pass) {
22132224
} else if (containsFunctionSignature(genEnv, pass.Mod, resultTy,
22142225
newSILType) &&
22152226
(resultTy != newSILType)) {
2216-
assert(loweredTy->getNumResults() == 1 && "Expected a single result");
2217-
SILResultInfo origResultInfo = loweredTy->getSingleResult();
2218-
SILResultInfo newSILResultInfo(newSILType.getASTType(),
2219-
origResultInfo.getConvention());
2227+
2228+
llvm::SmallVector<SILResultInfo, 2> newSILResultInfo;
2229+
if (auto tupleType = newSILType.getAs<TupleType>()) {
2230+
auto originalResults = loweredTy->getResults();
2231+
for (unsigned int i = 0; i < originalResults.size(); ++i) {
2232+
auto origResultInfo = originalResults[i];
2233+
auto canElem = tupleType.getElementType(i);
2234+
SILType objectType = SILType::getPrimitiveObjectType(canElem);
2235+
auto newResult = SILResultInfo(objectType.getASTType(), origResultInfo.getConvention());
2236+
newSILResultInfo.push_back(newResult);
2237+
}
2238+
} else {
2239+
assert(loweredTy->getNumResults() == 1 && "Expected a single result");
2240+
auto origResultInfo = loweredTy->getSingleResult();
2241+
auto newResult = SILResultInfo(newSILType.getASTType(), origResultInfo.getConvention());
2242+
newSILResultInfo.push_back(newResult);
2243+
}
2244+
22202245
auto NewTy = SILFunctionType::get(
22212246
loweredTy->getGenericSignature(), loweredTy->getExtInfo(),
22222247
loweredTy->getCoroutineKind(),

test/IRGen/big_types_corner_cases.swift

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,80 @@ class ClassWithLoadableStructWithBiggerString {
271271
return LoadableStructWithBiggerString(a1: BiggerString(str:"", double:0.0), a2: [], a3: [])
272272
}
273273
}
274+
275+
//===----------------------------------------------------------------------===//
276+
// SR-8076
277+
//===----------------------------------------------------------------------===//
278+
public typealias sr8076_Filter = (BigStruct) -> Bool
279+
280+
public protocol sr8076_Query {
281+
associatedtype Returned
282+
}
283+
284+
public protocol sr8076_ProtoQueryHandler {
285+
func forceHandle_1<Q: sr8076_Query>(query: Q) -> Void
286+
func forceHandle_2<Q: sr8076_Query>(query: Q) -> (Q.Returned, BigStruct?)
287+
func forceHandle_3<Q: sr8076_Query>(query: Q) -> (Q.Returned, sr8076_Filter?)
288+
func forceHandle_4<Q: sr8076_Query>(query: Q) throws -> (Q.Returned, sr8076_Filter?)
289+
}
290+
291+
public protocol sr8076_QueryHandler: sr8076_ProtoQueryHandler {
292+
associatedtype Handled: sr8076_Query
293+
func handle_1(query: Handled) -> Void
294+
func handle_2(query: Handled) -> (Handled.Returned, BigStruct?)
295+
func handle_3(query: Handled) -> (Handled.Returned, sr8076_Filter?)
296+
func handle_4(query: Handled) throws -> (Handled.Returned, sr8076_Filter?)
297+
}
298+
299+
300+
public extension sr8076_QueryHandler {
301+
302+
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$S22big_types_corner_cases19sr8076_QueryHandlerPAAE13forceHandle_15queryyqd___tAA0e1_F0Rd__lF"(%swift.opaque* noalias nocapture, %swift.type*{{.*}}, %swift.type*{{.*}}, i8** {{.*}}.sr8076_QueryHandler, i8** {{.*}}.sr8076_Query, %swift.opaque* noalias nocapture swiftself)
303+
// CHECK: call swiftcc void {{.*}}(%swift.opaque* noalias nocapture {{.*}}, %swift.refcounted* swiftself {{.*}})
304+
// CHECK: ret void
305+
func forceHandle_1<Q: sr8076_Query>(query: Q) -> Void {
306+
guard let body = handle_1 as? (Q) -> Void else {
307+
fatalError("handler \(self) is expected to handle query \(query)")
308+
}
309+
body(query)
310+
}
311+
312+
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$S22big_types_corner_cases19sr8076_QueryHandlerPAAE13forceHandle_25query8ReturnedQyd___AA9BigStructVSgtqd___tAA0e1_F0Rd__lF"(%T22big_types_corner_cases9BigStructVSg* noalias nocapture sret, %swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type*{{.*}}, %swift.type*{{.*}}, i8** {{.*}}.sr8076_QueryHandler, i8** {{.*}}.sr8076_Query, %swift.opaque* noalias nocapture swiftself)
313+
// CHECK: [[ALLOC:%.*]] = alloca %T22big_types_corner_cases9BigStructVSg
314+
// CHECK: call swiftcc void {{.*}}(%T22big_types_corner_cases9BigStructVSg* noalias nocapture sret [[ALLOC]], %swift.opaque* noalias nocapture {{.*}}, %swift.opaque* noalias nocapture {{.*}}, %swift.refcounted* swiftself {{.*}})
315+
// CHECK: ret void
316+
func forceHandle_2<Q: sr8076_Query>(query: Q) -> (Q.Returned, BigStruct?) {
317+
guard let body = handle_2 as? (Q) -> (Q.Returned, BigStruct?) else {
318+
fatalError("handler \(self) is expected to handle query \(query)")
319+
}
320+
return body(query)
321+
}
322+
323+
// CHECK-LABEL-64: define{{( dllexport)?}}{{( protected)?}} swiftcc { i64, i64 } @"$S22big_types_corner_cases19sr8076_QueryHandlerPAAE13forceHandle_35query8ReturnedQyd___SbAA9BigStructVcSgtqd___tAA0e1_F0Rd__lF"(%swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type*{{.*}}, %swift.type*{{.*}}, i8** {{.*}}.sr8076_QueryHandler, i8** {{.*}}.sr8076_Query, %swift.opaque* noalias nocapture swiftself)
324+
// CHECK-64: {{.*}} = call swiftcc { i64, i64 } {{.*}}(%swift.opaque* noalias nocapture {{.*}}, %swift.opaque* noalias nocapture {{.*}}, %swift.refcounted* swiftself {{.*}})
325+
// CHECK-64: ret { i64, i64 }
326+
327+
// CHECK-LABEL-32: define{{( dllexport)?}}{{( protected)?}} swiftcc { i32, i32} @"$S22big_types_corner_cases19sr8076_QueryHandlerPAAE13forceHandle_35query8ReturnedQyd___SbAA9BigStructVcSgtqd___tAA0e1_F0Rd__lF"(%swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type*{{.*}}, %swift.type*{{.*}}, i8** {{.*}}.sr8076_QueryHandler, i8** {{.*}}.sr8076_Query, %swift.opaque* noalias nocapture swiftself)
328+
// CHECK-32: {{.*}} = call swiftcc { i32, i32 } {{.*}}(%swift.opaque* noalias nocapture {{.*}}, %swift.opaque* noalias nocapture {{.*}}, %swift.refcounted* swiftself {{.*}})
329+
// CHECK-32: ret { i32, i32 }
330+
func forceHandle_3<Q: sr8076_Query>(query: Q) -> (Q.Returned, sr8076_Filter?) {
331+
guard let body = handle_3 as? (Q) -> (Q.Returned, sr8076_Filter?) else {
332+
fatalError("handler \(self) is expected to handle query \(query)")
333+
}
334+
return body(query)
335+
}
336+
337+
// CHECK-LABEL-64: define{{( dllexport)?}}{{( protected)?}} swiftcc { i64, i64 } @"$S22big_types_corner_cases19sr8076_QueryHandlerPAAE13forceHandle_45query8ReturnedQyd___SbAA9BigStructVcSgtqd___tKAA0e1_F0Rd__lF"(%swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type*{{.*}}, %swift.type*{{.*}}, i8** {{.*}}.sr8076_QueryHandler, i8** {{.*}}.sr8076_Query, %swift.opaque* noalias nocapture swiftself, %swift.error** swifterror)
338+
// CHECK-64: {{.*}} = call swiftcc { i64, i64 } {{.*}}(%swift.opaque* noalias nocapture {{.*}}, %swift.opaque* noalias nocapture {{.*}}, %swift.refcounted* swiftself {{.*}}, %swift.error** nocapture swifterror {{.*}})
339+
// CHECK-64: ret { i64, i64 }
340+
341+
// CHECK-LABEL-32: define{{( dllexport)?}}{{( protected)?}} swiftcc { i32, i32} @"$S22big_types_corner_cases19sr8076_QueryHandlerPAAE13forceHandle_45query8ReturnedQyd___SbAA9BigStructVcSgtqd___tKAA0e1_F0Rd__lF"(%swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type*{{.*}}, %swift.type*{{.*}}, i8** {{.*}}.sr8076_QueryHandler, i8** {{.*}}.sr8076_Query, %swift.opaque* noalias nocapture swiftself, %swift.error** swifterror)
342+
// CHECK-32: {{.*}} = call swiftcc { i32, i32 } {{.*}}(%swift.opaque* noalias nocapture {{.*}}, %swift.opaque* noalias nocapture {{.*}}, %swift.refcounted* swiftself {{.*}}, %swift.error** nocapture {{.*}})
343+
// CHECK-32: ret { i32, i32 }
344+
func forceHandle_4<Q: sr8076_Query>(query: Q) throws -> (Q.Returned, sr8076_Filter?) {
345+
guard let body = handle_4 as? (Q) throws -> (Q.Returned, sr8076_Filter?) else {
346+
fatalError("handler \(self) is expected to handle query \(query)")
347+
}
348+
return try body(query)
349+
}
350+
}

0 commit comments

Comments
 (0)