@@ -891,6 +891,37 @@ void SILGenFunction::collectThunkParams(
891
891
}
892
892
}
893
893
894
+ // / If the inner function we are calling (with type \c fnType) from the thunk
895
+ // / created by \c SGF requires an indirect error argument, returns that
896
+ // / argument.
897
+ static llvm::Optional<SILValue>
898
+ emitThunkIndirectErrorArgument (SILGenFunction &SGF, SILLocation loc,
899
+ CanSILFunctionType fnType) {
900
+ // If the function we're calling has as indirect error result, create an
901
+ // argument for it.
902
+ auto innerError = fnType->getOptionalErrorResult ();
903
+ if (!innerError || innerError->getConvention () != ResultConvention::Indirect)
904
+ return llvm::None;
905
+
906
+ // If the type of the indirect error is the same for both the inner
907
+ // function and the thunk, so we can re-use the indirect error slot.
908
+ auto loweredErrorResultType = SGF.getSILType (*innerError, fnType);
909
+ if (SGF.IndirectErrorResult &&
910
+ SGF.IndirectErrorResult ->getType ().getObjectType ()
911
+ == loweredErrorResultType) {
912
+ return SGF.IndirectErrorResult ;
913
+ }
914
+
915
+ // The type of the indirect error in the inner function differs from
916
+ // that of the thunk, or the thunk has a direct error, so allocate a
917
+ // stack location for the inner indirect error.
918
+ SILValue innerIndirectErrorAddr =
919
+ SGF.B .createAllocStack (loc, loweredErrorResultType);
920
+ SGF.enterDeallocStackCleanup (innerIndirectErrorAddr);
921
+
922
+ return innerIndirectErrorAddr;
923
+ }
924
+
894
925
namespace {
895
926
896
927
class TranslateIndirect : public Cleanup {
@@ -4847,27 +4878,9 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
4847
4878
4848
4879
// If the function we're calling has as indirect error result, create an
4849
4880
// argument for it.
4850
- SILValue innerIndirectErrorAddr;
4851
- if (auto innerError = fnType->getOptionalErrorResult ()) {
4852
- if (innerError->getConvention () == ResultConvention::Indirect) {
4853
- auto loweredErrorResultType = SGF.getSILType (*innerError, fnType);
4854
- if (SGF.IndirectErrorResult &&
4855
- SGF.IndirectErrorResult ->getType ().getObjectType ()
4856
- == loweredErrorResultType) {
4857
- // The type of the indirect error is the same for both the inner
4858
- // function and the thunk, so we can re-use the indirect error slot.
4859
- innerIndirectErrorAddr = SGF.IndirectErrorResult ;
4860
- } else {
4861
- // The type of the indirect error in the inner function differs from
4862
- // that of the thunk, or the thunk has a direct error, so allocate a
4863
- // stack location for the inner indirect error.
4864
- innerIndirectErrorAddr =
4865
- SGF.B .createAllocStack (loc, loweredErrorResultType);
4866
- SGF.enterDeallocStackCleanup (innerIndirectErrorAddr);
4867
- }
4868
-
4869
- argValues.push_back (innerIndirectErrorAddr);
4870
- }
4881
+ if (auto innerIndirectErrorAddr =
4882
+ emitThunkIndirectErrorArgument (SGF, loc, fnType)) {
4883
+ argValues.push_back (*innerIndirectErrorAddr);
4871
4884
}
4872
4885
4873
4886
// Add the rest of the arguments.
@@ -5175,7 +5188,8 @@ static void buildWithoutActuallyEscapingThunkBody(SILGenFunction &SGF,
5175
5188
5176
5189
SmallVector<ManagedValue, 8 > params;
5177
5190
SmallVector<ManagedValue, 8 > indirectResults;
5178
- SGF.collectThunkParams (loc, params, &indirectResults);
5191
+ SmallVector<ManagedValue, 1 > indirectErrorResults;
5192
+ SGF.collectThunkParams (loc, params, &indirectResults, &indirectErrorResults);
5179
5193
5180
5194
// Ignore the self parameter at the SIL level. IRGen will use it to
5181
5195
// recover type metadata.
@@ -5185,13 +5199,16 @@ static void buildWithoutActuallyEscapingThunkBody(SILGenFunction &SGF,
5185
5199
ManagedValue fnValue = params.pop_back_val ();
5186
5200
auto fnType = fnValue.getType ().castTo <SILFunctionType>();
5187
5201
5202
+ // Forward indirect result arguments.
5188
5203
SmallVector<SILValue, 8 > argValues;
5189
5204
if (!indirectResults.empty ()) {
5190
5205
for (auto result : indirectResults)
5191
5206
argValues.push_back (result.getLValueAddress ());
5192
5207
}
5193
5208
5194
- // Forward indirect result arguments.
5209
+ // Forward indirect error arguments.
5210
+ for (auto indirectError : indirectErrorResults)
5211
+ argValues.push_back (indirectError.getLValueAddress ());
5195
5212
5196
5213
// Add the rest of the arguments.
5197
5214
forwardFunctionArguments (SGF, loc, fnType, params, argValues);
@@ -5376,14 +5393,18 @@ ManagedValue SILGenFunction::getThunkedAutoDiffLinearMap(
5376
5393
SILGenFunction thunkSGF (SGM, *thunk, FunctionDC);
5377
5394
SmallVector<ManagedValue, 4 > params;
5378
5395
SmallVector<ManagedValue, 4 > thunkIndirectResults;
5379
- thunkSGF.collectThunkParams (loc, params, &thunkIndirectResults);
5396
+ SmallVector<ManagedValue, 4 > thunkIndirectErrorResults;
5397
+ thunkSGF.collectThunkParams (
5398
+ loc, params, &thunkIndirectResults, &thunkIndirectErrorResults);
5380
5399
5381
5400
SILFunctionConventions fromConv (fromType, getModule ());
5382
5401
SILFunctionConventions toConv (toType, getModule ());
5383
5402
if (!toConv.useLoweredAddresses ()) {
5384
5403
SmallVector<ManagedValue, 4 > thunkArguments;
5385
5404
for (auto indRes : thunkIndirectResults)
5386
5405
thunkArguments.push_back (indRes);
5406
+ for (auto indErrRes : thunkIndirectErrorResults)
5407
+ thunkArguments.push_back (indErrRes);
5387
5408
thunkArguments.append (params.begin (), params.end ());
5388
5409
SmallVector<SILParameterInfo, 4 > toParameters (
5389
5410
toConv.getParameters ().begin (), toConv.getParameters ().end ());
@@ -5392,7 +5413,8 @@ ManagedValue SILGenFunction::getThunkedAutoDiffLinearMap(
5392
5413
// Handle self reordering.
5393
5414
// - For pullbacks: reorder result infos.
5394
5415
// - For differentials: reorder parameter infos and arguments.
5395
- auto numIndirectResults = thunkIndirectResults.size ();
5416
+ auto numIndirectResults =
5417
+ thunkIndirectResults.size () + thunkIndirectErrorResults.size ();
5396
5418
if (reorderSelf && linearMapKind == AutoDiffLinearMapKind::Pullback &&
5397
5419
toResults.size () > 1 ) {
5398
5420
std::rotate (toResults.begin (), toResults.end () - 1 , toResults.end ());
@@ -5464,6 +5486,8 @@ ManagedValue SILGenFunction::getThunkedAutoDiffLinearMap(
5464
5486
SmallVector<ManagedValue, 4 > thunkArguments;
5465
5487
thunkArguments.append (thunkIndirectResults.begin (),
5466
5488
thunkIndirectResults.end ());
5489
+ thunkArguments.append (thunkIndirectErrorResults.begin (),
5490
+ thunkIndirectErrorResults.end ());
5467
5491
thunkArguments.append (params.begin (), params.end ());
5468
5492
SmallVector<SILParameterInfo, 4 > toParameters (toConv.getParameters ().begin (),
5469
5493
toConv.getParameters ().end ());
@@ -5710,7 +5734,9 @@ SILFunction *SILGenModule::getOrCreateCustomDerivativeThunk(
5710
5734
SILGenFunction thunkSGF (*this , *thunk, customDerivativeFn->getDeclContext ());
5711
5735
SmallVector<ManagedValue, 4 > params;
5712
5736
SmallVector<ManagedValue, 4 > indirectResults;
5713
- thunkSGF.collectThunkParams (loc, params, &indirectResults);
5737
+ SmallVector<ManagedValue, 1 > indirectErrorResults;
5738
+ thunkSGF.collectThunkParams (
5739
+ loc, params, &indirectResults, &indirectErrorResults);
5714
5740
5715
5741
auto *fnRef = thunkSGF.B .createFunctionRef (loc, customDerivativeFn);
5716
5742
auto fnRefType =
@@ -5754,6 +5780,8 @@ SILFunction *SILGenModule::getOrCreateCustomDerivativeThunk(
5754
5780
SmallVector<SILValue, 8 > arguments;
5755
5781
for (auto indRes : indirectResults)
5756
5782
arguments.push_back (indRes.getLValueAddress ());
5783
+ for (auto indErrorRes : indirectErrorResults)
5784
+ arguments.push_back (indErrorRes.getLValueAddress ());
5757
5785
forwardFunctionArguments (thunkSGF, loc, fnRefType, params, arguments);
5758
5786
5759
5787
// Apply function argument.
@@ -6187,6 +6215,13 @@ SILGenFunction::emitVTableThunk(SILDeclRef base,
6187
6215
inputOrigType.getFunctionResultType (),
6188
6216
inputSubstType.getResult (),
6189
6217
derivedFTy, thunkTy);
6218
+
6219
+ // If the function we're calling has as indirect error result, create an
6220
+ // argument for it.
6221
+ if (auto innerIndirectErrorAddr =
6222
+ emitThunkIndirectErrorArgument (*this , loc, derivedFTy)) {
6223
+ args.push_back (*innerIndirectErrorAddr);
6224
+ }
6190
6225
}
6191
6226
6192
6227
// Then, the arguments.
@@ -6571,6 +6606,13 @@ void SILGenFunction::emitProtocolWitness(
6571
6606
reqtOrigTy.getFunctionResultType (),
6572
6607
reqtSubstTy.getResult (),
6573
6608
witnessFTy, thunkTy);
6609
+
6610
+ // If the function we're calling has as indirect error result, create an
6611
+ // argument for it.
6612
+ if (auto innerIndirectErrorAddr =
6613
+ emitThunkIndirectErrorArgument (*this , loc, witnessFTy)) {
6614
+ args.push_back (*innerIndirectErrorAddr);
6615
+ }
6574
6616
}
6575
6617
6576
6618
// - the rest of the arguments
0 commit comments