@@ -460,11 +460,11 @@ getSubstitutionsForCallee(SILModule &module, CanSILFunctionType baseCalleeType,
460
460
baseCalleeSig);
461
461
}
462
462
463
- static ApplyInst * replaceApplyInst (SILBuilder &builder, SILLocation loc,
464
- ApplyInst *oldAI, SILValue newFn,
465
- SubstitutionMap newSubs ,
466
- ArrayRef<SILValue> newArgs ,
467
- ArrayRef<SILValue> newArgBorrows) {
463
+ // Return the new apply and true if a cast required CFG modification.
464
+ static std::pair< ApplyInst *, bool /* changedCFG */ >
465
+ replaceApplyInst (SILBuilder &builder, SILLocation loc, ApplyInst *oldAI ,
466
+ SILValue newFn, SubstitutionMap newSubs ,
467
+ ArrayRef<SILValue> newArgs, ArrayRef<SILValue> newArgBorrows) {
468
468
auto *newAI =
469
469
builder.createApply (loc, newFn, newSubs, newArgs, oldAI->isNonThrowing ());
470
470
@@ -475,15 +475,15 @@ static ApplyInst *replaceApplyInst(SILBuilder &builder, SILLocation loc,
475
475
}
476
476
477
477
// Check if any casting is required for the return value.
478
- SILValue resultValue = castValueToABICompatibleType (
478
+ auto castRes = castValueToABICompatibleType (
479
479
&builder, loc, newAI, newAI->getType (), oldAI->getType ());
480
480
481
- oldAI->replaceAllUsesWith (resultValue );
482
- return newAI;
481
+ oldAI->replaceAllUsesWith (castRes. first );
482
+ return { newAI, castRes. second } ;
483
483
}
484
484
485
485
// Return the new try_apply and true if a cast required CFG modification.
486
- static std::pair<TryApplyInst *, bool >
486
+ static std::pair<TryApplyInst *, bool /* changedCFG */ >
487
487
replaceTryApplyInst (SILBuilder &builder, SILLocation loc, TryApplyInst *oldTAI,
488
488
SILValue newFn, SubstitutionMap newSubs,
489
489
ArrayRef<SILValue> newArgs, SILFunctionConventions conv,
@@ -531,20 +531,22 @@ replaceTryApplyInst(SILBuilder &builder, SILLocation loc, TryApplyInst *oldTAI,
531
531
builder.setInsertionPoint (resultBB);
532
532
533
533
SILValue resultValue = resultBB->getArgument (0 );
534
- resultValue = castValueToABICompatibleType (&builder, loc, resultValue,
535
- newResultTy, oldResultTy);
534
+ std::tie ( resultValue, std::ignore) = castValueToABICompatibleType (
535
+ &builder, loc, resultValue, newResultTy, oldResultTy);
536
536
builder.createBranch (loc, normalBB, {resultValue});
537
537
}
538
538
539
539
builder.setInsertionPoint (normalBB->begin ());
540
540
return {newTAI, resultCastRequired};
541
541
}
542
542
543
- static BeginApplyInst *
543
+ // Return the new begin_apply and true if a cast required CFG modification.
544
+ static std::pair<BeginApplyInst *, bool /* changedCFG */ >
544
545
replaceBeginApplyInst (SILBuilder &builder, SILLocation loc,
545
546
BeginApplyInst *oldBAI, SILValue newFn,
546
547
SubstitutionMap newSubs, ArrayRef<SILValue> newArgs,
547
548
ArrayRef<SILValue> newArgBorrows) {
549
+ bool changedCFG = false ;
548
550
auto *newBAI = builder.createBeginApply (loc, newFn, newSubs, newArgs,
549
551
oldBAI->isNonThrowing ());
550
552
@@ -558,13 +560,14 @@ replaceBeginApplyInst(SILBuilder &builder, SILLocation loc,
558
560
for (auto i : indices (oldYields)) {
559
561
auto oldYield = oldYields[i];
560
562
auto newYield = newYields[i];
561
- newYield = castValueToABICompatibleType (
563
+ auto yieldCastRes = castValueToABICompatibleType (
562
564
&builder, loc, newYield, newYield->getType (), oldYield->getType ());
563
- oldYield->replaceAllUsesWith (newYield);
565
+ oldYield->replaceAllUsesWith (yieldCastRes.first );
566
+ changedCFG |= yieldCastRes.second ;
564
567
}
565
568
566
569
if (newArgBorrows.empty ())
567
- return newBAI;
570
+ return { newBAI, changedCFG} ;
568
571
569
572
SILValue token = newBAI->getTokenResult ();
570
573
@@ -579,10 +582,11 @@ replaceBeginApplyInst(SILBuilder &builder, SILLocation loc,
579
582
}
580
583
}
581
584
582
- return newBAI;
585
+ return { newBAI, changedCFG} ;
583
586
}
584
587
585
- static PartialApplyInst *
588
+ // Return the new partial_apply and true if a cast required CFG modification.
589
+ static std::pair<PartialApplyInst *, bool /* changedCFG */ >
586
590
replacePartialApplyInst (SILBuilder &builder, SILLocation loc,
587
591
PartialApplyInst *oldPAI, SILValue newFn,
588
592
SubstitutionMap newSubs, ArrayRef<SILValue> newArgs) {
@@ -592,25 +596,24 @@ replacePartialApplyInst(SILBuilder &builder, SILLocation loc,
592
596
builder.createPartialApply (loc, newFn, newSubs, newArgs, convention);
593
597
594
598
// Check if any casting is required for the partially-applied function.
595
- SILValue resultValue = castValueToABICompatibleType (
599
+ auto castRes = castValueToABICompatibleType (
596
600
&builder, loc, newPAI, newPAI->getType (), oldPAI->getType ());
597
- oldPAI->replaceAllUsesWith (resultValue );
601
+ oldPAI->replaceAllUsesWith (castRes. first );
598
602
599
- return newPAI;
603
+ return { newPAI, castRes. second } ;
600
604
}
601
605
602
606
// Return the new apply and true if the CFG was also modified.
603
- static std::pair<ApplySite, bool >
607
+ static std::pair<ApplySite, bool /* changedCFG */ >
604
608
replaceApplySite (SILBuilder &builder, SILLocation loc, ApplySite oldAS,
605
609
SILValue newFn, SubstitutionMap newSubs,
606
610
ArrayRef<SILValue> newArgs, SILFunctionConventions conv,
607
611
ArrayRef<SILValue> newArgBorrows) {
608
612
switch (oldAS.getKind ()) {
609
613
case ApplySiteKind::ApplyInst: {
610
614
auto *oldAI = cast<ApplyInst>(oldAS);
611
- return {replaceApplyInst (builder, loc, oldAI, newFn, newSubs, newArgs,
612
- newArgBorrows),
613
- false };
615
+ return replaceApplyInst (builder, loc, oldAI, newFn, newSubs, newArgs,
616
+ newArgBorrows);
614
617
}
615
618
case ApplySiteKind::TryApplyInst: {
616
619
auto *oldTAI = cast<TryApplyInst>(oldAS);
@@ -619,16 +622,14 @@ replaceApplySite(SILBuilder &builder, SILLocation loc, ApplySite oldAS,
619
622
}
620
623
case ApplySiteKind::BeginApplyInst: {
621
624
auto *oldBAI = dyn_cast<BeginApplyInst>(oldAS);
622
- return {replaceBeginApplyInst (builder, loc, oldBAI, newFn, newSubs, newArgs,
623
- newArgBorrows),
624
- false };
625
+ return replaceBeginApplyInst (builder, loc, oldBAI, newFn, newSubs, newArgs,
626
+ newArgBorrows);
625
627
}
626
628
case ApplySiteKind::PartialApplyInst: {
627
629
assert (newArgBorrows.empty ());
628
630
auto *oldPAI = cast<PartialApplyInst>(oldAS);
629
- return {
630
- replacePartialApplyInst (builder, loc, oldPAI, newFn, newSubs, newArgs),
631
- false };
631
+ return replacePartialApplyInst (builder, loc, oldPAI, newFn, newSubs,
632
+ newArgs);
632
633
}
633
634
}
634
635
llvm_unreachable (" covered switch" );
@@ -734,10 +735,11 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd,
734
735
// / return the result value of the new ApplyInst if created one or null.
735
736
// /
736
737
// / Return the new apply and true if the CFG was also modified.
737
- std::pair<FullApplySite, bool >
738
+ std::pair<FullApplySite, bool /* changedCFG */ >
738
739
swift::devirtualizeClassMethod (FullApplySite applySite,
739
740
SILValue classOrMetatype, ClassDecl *cd,
740
741
OptRemark::Emitter *ore) {
742
+ bool changedCFG = false ;
741
743
LLVM_DEBUG (llvm::dbgs () << " Trying to devirtualize : "
742
744
<< *applySite.getInstruction ());
743
745
@@ -775,9 +777,11 @@ swift::devirtualizeClassMethod(FullApplySite applySite,
775
777
776
778
auto indirectResultArgIter = applySite.getIndirectSILResults ().begin ();
777
779
for (auto resultTy : substConv.getIndirectSILResultTypes ()) {
778
- newArgs. push_back ( castValueToABICompatibleType (
780
+ auto castRes = castValueToABICompatibleType (
779
781
&builder, loc, *indirectResultArgIter, indirectResultArgIter->getType (),
780
- resultTy));
782
+ resultTy);
783
+ newArgs.push_back (castRes.first );
784
+ changedCFG |= castRes.second ;
781
785
++indirectResultArgIter;
782
786
}
783
787
@@ -793,15 +797,18 @@ swift::devirtualizeClassMethod(FullApplySite applySite,
793
797
arg = borrowBuilder.createBeginBorrow (loc, arg);
794
798
newArgBorrows.push_back (arg);
795
799
}
796
- arg = castValueToABICompatibleType (&builder, loc, arg,
800
+ auto argCastRes = castValueToABICompatibleType (&builder, loc, arg,
797
801
paramArgIter->getType (), paramType);
798
- newArgs.push_back (arg);
802
+
803
+ newArgs.push_back (argCastRes.first );
804
+ changedCFG |= argCastRes.second ;
799
805
++paramArgIter;
800
806
}
801
807
ApplySite newAS;
802
- bool modifiedCFG ;
803
- std::tie (newAS, modifiedCFG ) = replaceApplySite (
808
+ bool neededCFGChange ;
809
+ std::tie (newAS, neededCFGChange ) = replaceApplySite (
804
810
builder, loc, applySite, fri, subs, newArgs, substConv, newArgBorrows);
811
+ changedCFG |= neededCFGChange;
805
812
FullApplySite newAI = FullApplySite::isa (newAS.getInstruction ());
806
813
assert (newAI);
807
814
@@ -815,7 +822,7 @@ swift::devirtualizeClassMethod(FullApplySite applySite,
815
822
});
816
823
NumClassDevirt++;
817
824
818
- return {newAI, modifiedCFG };
825
+ return {newAI, changedCFG };
819
826
}
820
827
821
828
std::pair<FullApplySite, bool > swift::tryDevirtualizeClassMethod (
@@ -971,6 +978,7 @@ static std::pair<ApplySite, bool>
971
978
devirtualizeWitnessMethod (ApplySite applySite, SILFunction *f,
972
979
ProtocolConformanceRef cRef,
973
980
OptRemark::Emitter *ore) {
981
+ bool changedCFG = false ;
974
982
// We know the witness thunk and the corresponding set of substitutions
975
983
// required to invoke the protocol method at this point.
976
984
auto &module = applySite.getModule ();
@@ -1012,8 +1020,10 @@ devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
1012
1020
arg = borrowBuilder.createBeginBorrow (applySite.getLoc (), arg);
1013
1021
borrowedArgs.push_back (arg);
1014
1022
}
1015
- arg = castValueToABICompatibleType (&argBuilder, applySite.getLoc (), arg,
1016
- arg->getType (), paramType);
1023
+ auto argCastRes = castValueToABICompatibleType (
1024
+ &argBuilder, applySite.getLoc (), arg, arg->getType (), paramType);
1025
+ arg = argCastRes.first ;
1026
+ changedCFG |= argCastRes.second ;
1017
1027
}
1018
1028
arguments.push_back (arg);
1019
1029
}
@@ -1026,10 +1036,11 @@ devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
1026
1036
auto *fri = applyBuilder.createFunctionRefFor (loc, f);
1027
1037
1028
1038
ApplySite newApplySite;
1029
- bool modifiedCFG ;
1030
- std::tie (newApplySite, modifiedCFG ) =
1039
+ bool neededCFGChange = false ;
1040
+ std::tie (newApplySite, neededCFGChange ) =
1031
1041
replaceApplySite (applyBuilder, loc, applySite, fri, subMap, arguments,
1032
1042
substConv, borrowedArgs);
1043
+ changedCFG |= neededCFGChange;
1033
1044
1034
1045
if (ore)
1035
1046
ore->emit ([&]() {
@@ -1039,7 +1050,7 @@ devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
1039
1050
<< " Devirtualized call to " << NV (" Method" , f);
1040
1051
});
1041
1052
NumWitnessDevirt++;
1042
- return {newApplySite, modifiedCFG };
1053
+ return {newApplySite, changedCFG };
1043
1054
}
1044
1055
1045
1056
static bool canDevirtualizeWitnessMethod (ApplySite applySite) {
0 commit comments