@@ -358,7 +358,8 @@ static void addIndirectResultAttributes(IRGenModule &IGM,
358
358
llvm::AttributeList &attrs,
359
359
unsigned paramIndex, bool allowSRet,
360
360
llvm::Type *storageType,
361
- const TypeInfo &typeInfo) {
361
+ const TypeInfo &typeInfo,
362
+ bool useInReg = false ) {
362
363
llvm::AttrBuilder b (IGM.getLLVMContext ());
363
364
b.addAttribute (llvm::Attribute::NoAlias);
364
365
// Bitwise takable value types are guaranteed not to capture
@@ -368,6 +369,8 @@ static void addIndirectResultAttributes(IRGenModule &IGM,
368
369
if (allowSRet) {
369
370
assert (storageType);
370
371
b.addStructRetAttr (storageType);
372
+ if (useInReg)
373
+ b.addAttribute (llvm::Attribute::InReg);
371
374
}
372
375
attrs = attrs.addParamAttributes (IGM.getLLVMContext (), paramIndex, b);
373
376
}
@@ -475,7 +478,7 @@ namespace {
475
478
476
479
private:
477
480
const TypeInfo &expand (SILParameterInfo param);
478
- llvm::Type *addIndirectResult (SILType resultType);
481
+ llvm::Type *addIndirectResult (SILType resultType, bool useInReg = false );
479
482
480
483
SILFunctionConventions getSILFuncConventions () const {
481
484
return SILFunctionConventions (FnType, IGM.getSILModule ());
@@ -533,11 +536,12 @@ namespace {
533
536
} // end namespace irgen
534
537
} // end namespace swift
535
538
536
- llvm::Type *SignatureExpansion::addIndirectResult (SILType resultType) {
539
+ llvm::Type *SignatureExpansion::addIndirectResult (SILType resultType,
540
+ bool useInReg) {
537
541
const TypeInfo &resultTI = IGM.getTypeInfo (resultType);
538
542
auto storageTy = resultTI.getStorageType ();
539
543
addIndirectResultAttributes (IGM, Attrs, ParamIRTypes.size (), claimSRet (),
540
- storageTy, resultTI);
544
+ storageTy, resultTI, useInReg );
541
545
addPointerParameter (storageTy);
542
546
return IGM.VoidTy ;
543
547
}
@@ -1449,9 +1453,15 @@ void SignatureExpansion::expandExternalSignatureTypes() {
1449
1453
// Generate function info for this signature.
1450
1454
auto extInfo = clang::FunctionType::ExtInfo ();
1451
1455
1452
- auto &FI = clang::CodeGen::arrangeFreeFunctionCall (IGM.ClangCodeGen ->CGM (),
1453
- clangResultTy, paramTys, extInfo,
1454
- clang::CodeGen::RequiredArgs::All);
1456
+ bool isCXXMethod =
1457
+ FnType->getRepresentation () == SILFunctionTypeRepresentation::CXXMethod;
1458
+ auto &FI = isCXXMethod ?
1459
+ clang::CodeGen::arrangeCXXMethodCall (IGM.ClangCodeGen ->CGM (),
1460
+ clangResultTy, paramTys, extInfo, {},
1461
+ clang::CodeGen::RequiredArgs::All) :
1462
+ clang::CodeGen::arrangeFreeFunctionCall (IGM.ClangCodeGen ->CGM (),
1463
+ clangResultTy, paramTys, extInfo, {},
1464
+ clang::CodeGen::RequiredArgs::All);
1455
1465
ForeignInfo.ClangInfo = &FI;
1456
1466
1457
1467
assert (FI.arg_size () == paramTys.size () &&
@@ -1573,16 +1583,14 @@ void SignatureExpansion::expandExternalSignatureTypes() {
1573
1583
if (returnInfo.isIndirect ()) {
1574
1584
auto resultType = getSILFuncConventions ().getSingleSILResultType (
1575
1585
IGM.getMaximalTypeExpansionContext ());
1576
- if (IGM.Triple .isWindowsMSVCEnvironment () &&
1577
- FnType->getRepresentation () ==
1578
- SILFunctionTypeRepresentation::CXXMethod) {
1586
+ if (returnInfo.isSRetAfterThis ()) {
1579
1587
// Windows ABI places `this` before the
1580
1588
// returned indirect values.
1581
1589
emitArg (0 );
1582
1590
firstParamToLowerNormally = 1 ;
1583
- addIndirectResult (resultType);
1591
+ addIndirectResult (resultType, returnInfo. getInReg () );
1584
1592
} else
1585
- addIndirectResult (resultType);
1593
+ addIndirectResult (resultType, returnInfo. getInReg () );
1586
1594
}
1587
1595
1588
1596
// Use a special IR type for passing block pointers.
@@ -2534,11 +2542,12 @@ class SyncCallEmission final : public CallEmission {
2534
2542
2535
2543
// Windows ABI places `this` before the
2536
2544
// returned indirect values.
2537
- bool isThisFirst = IGF.IGM .Triple .isWindowsMSVCEnvironment ();
2538
- if (!isThisFirst)
2545
+ auto &returnInfo =
2546
+ getCallee ().getForeignInfo ().ClangInfo ->getReturnInfo ();
2547
+ if (returnInfo.isIndirect () && !returnInfo.isSRetAfterThis ())
2539
2548
passIndirectResults ();
2540
2549
adjusted.add (arg);
2541
- if (isThisFirst )
2550
+ if (returnInfo. isIndirect () && returnInfo. isSRetAfterThis () )
2542
2551
passIndirectResults ();
2543
2552
}
2544
2553
@@ -3115,9 +3124,10 @@ void CallEmission::emitToUnmappedMemory(Address result) {
3115
3124
assert (LastArgWritten == 1 && " emitting unnaturally to indirect result" );
3116
3125
3117
3126
Args[0 ] = result.getAddress ();
3118
- if (IGF.IGM .Triple .isWindowsMSVCEnvironment () &&
3119
- getCallee ().getRepresentation () ==
3120
- SILFunctionTypeRepresentation::CXXMethod &&
3127
+
3128
+ auto *FI = getCallee ().getForeignInfo ().ClangInfo ;
3129
+ if (FI && FI->getReturnInfo ().isIndirect () &&
3130
+ FI->getReturnInfo ().isSRetAfterThis () &&
3121
3131
Args[1 ] == getCallee ().getCXXMethodSelf ()) {
3122
3132
// C++ methods in MSVC ABI pass `this` before the
3123
3133
// indirectly returned value.
@@ -3482,10 +3492,10 @@ void CallEmission::emitToExplosion(Explosion &out, bool isOutlined) {
3482
3492
emitToMemory (temp, substResultTI, isOutlined);
3483
3493
return ;
3484
3494
}
3485
- if (IGF. IGM . Triple . isWindowsMSVCEnvironment () &&
3486
- getCallee ().getRepresentation () ==
3487
- SILFunctionTypeRepresentation::CXXMethod &&
3488
- substResultType.isVoid ()) {
3495
+
3496
+ auto *FI = getCallee ().getForeignInfo (). ClangInfo ;
3497
+ if (FI && FI-> getReturnInfo (). isIndirect () &&
3498
+ FI-> getReturnInfo (). isSRetAfterThis () && substResultType.isVoid ()) {
3489
3499
// Some C++ methods return a value but are imported as
3490
3500
// returning `Void` (e.g. `operator +=`). In this case
3491
3501
// we should allocate the correct temp indirect return
0 commit comments