@@ -602,10 +602,10 @@ bool ReabstractionInfo::canBeSpecialized(ApplySite Apply, SILFunction *Callee,
602
602
ReabstractionInfo::ReabstractionInfo (
603
603
ModuleDecl *targetModule, bool isWholeModule, ApplySite Apply,
604
604
SILFunction *Callee, SubstitutionMap ParamSubs, SerializedKind_t Serialized,
605
- bool ConvertIndirectToDirect, bool dropMetatypeArgs ,
605
+ bool ConvertIndirectToDirect, bool dropUnusedArguments ,
606
606
OptRemark::Emitter *ORE)
607
607
: ConvertIndirectToDirect(ConvertIndirectToDirect),
608
- dropMetatypeArgs(dropMetatypeArgs ), M(&Callee->getModule ()),
608
+ dropUnusedArguments(dropUnusedArguments ), M(&Callee->getModule ()),
609
609
TargetModule(targetModule), isWholeModule(isWholeModule),
610
610
Serialized(Serialized) {
611
611
if (!prepareAndCheck (Apply, Callee, ParamSubs, ORE))
@@ -737,7 +737,7 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
737
737
SubstitutedType->getParameters ().size ();
738
738
Conversions.resize (NumArgs);
739
739
TrivialArgs.resize (NumArgs);
740
- droppedMetatypeArgs .resize (NumArgs);
740
+ droppedArguments .resize (NumArgs);
741
741
742
742
if (SubstitutedType->getNumDirectFormalResults () == 0 ) {
743
743
// The original function has no direct result yet. Try to convert the first
@@ -763,9 +763,11 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
763
763
}
764
764
765
765
// Try to convert indirect incoming parameters to direct parameters.
766
+ unsigned i = 0 ;
766
767
for (SILParameterInfo PI : SubstitutedType->getParameters ()) {
767
768
auto IdxToInsert = IdxForParam;
768
769
++IdxForParam;
770
+ unsigned argIdx = i++;
769
771
770
772
SILFunctionConventions substConv (SubstitutedType, getModule ());
771
773
TypeCategory tc = getParamTypeCategory (PI, substConv, getResilienceExpansion ());
@@ -776,6 +778,23 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
776
778
case ParameterConvention::Indirect_In_CXX:
777
779
case ParameterConvention::Indirect_In:
778
780
case ParameterConvention::Indirect_In_Guaranteed: {
781
+ if (Callee && Apply && dropUnusedArguments) {
782
+ // If there is no read from an indirect argument, this argument has to
783
+ // be dropped. At the call site the store to the argument's memory location
784
+ // could have been removed (based on the callee's memory effects).
785
+ // Therefore, converting such an unused indirect argument to a direct
786
+ // argument, would load an uninitialized value at the call site.
787
+ // This would lead to verifier errors and in worst case to a miscompile
788
+ // because IRGen can implicitly use dead arguments, e.g. for getting the
789
+ // type of a class reference.
790
+ if (FullApplySite fas = Apply.asFullApplySite ()) {
791
+ Operand &op = fas.getOperandsWithoutIndirectResults ()[argIdx];
792
+ if (!Callee->argumentMayRead (&op, op.get ())) {
793
+ droppedArguments.set (IdxToInsert);
794
+ break ;
795
+ }
796
+ }
797
+ }
779
798
Conversions.set (IdxToInsert);
780
799
if (tc == LoadableAndTrivial)
781
800
TrivialArgs.set (IdxToInsert);
@@ -799,8 +818,8 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
799
818
case ParameterConvention::Direct_Unowned:
800
819
case ParameterConvention::Direct_Guaranteed: {
801
820
CanType ty = PI.getInterfaceType ();
802
- if (dropMetatypeArgs && isa<MetatypeType>(ty) && !ty->hasArchetype ())
803
- droppedMetatypeArgs .set (IdxToInsert);
821
+ if (dropUnusedArguments && isa<MetatypeType>(ty) && !ty->hasArchetype ())
822
+ droppedArguments .set (IdxToInsert);
804
823
break ;
805
824
}
806
825
}
@@ -887,15 +906,15 @@ ReabstractionInfo::createSubstitutedType(SILFunction *OrigF,
887
906
}
888
907
889
908
CanSILFunctionType ReabstractionInfo::createThunkType (PartialApplyInst *forPAI) const {
890
- if (!droppedMetatypeArgs .any ())
909
+ if (!droppedArguments .any ())
891
910
return SubstitutedType;
892
911
893
912
llvm::SmallVector<SILParameterInfo, 8 > newParams;
894
913
auto params = SubstitutedType->getParameters ();
895
914
unsigned firstAppliedParamIdx = params.size () - forPAI->getArguments ().size ();
896
915
897
916
for (unsigned paramIdx = 0 ; paramIdx < params.size (); ++paramIdx) {
898
- if (paramIdx >= firstAppliedParamIdx && isDroppedMetatypeArg (param2ArgIndex (paramIdx)))
917
+ if (paramIdx >= firstAppliedParamIdx && isDroppedArgument (param2ArgIndex (paramIdx)))
899
918
continue ;
900
919
newParams.push_back (params[paramIdx]);
901
920
}
@@ -968,7 +987,7 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const {
968
987
unsigned paramIdx = idx++;
969
988
PI = PI.getUnsubstituted (M, SubstFTy, context);
970
989
971
- if (isDroppedMetatypeArg (param2ArgIndex (paramIdx))) {
990
+ if (isDroppedArgument (param2ArgIndex (paramIdx))) {
972
991
if (SubstFTy->hasSelfParam () && paramIdx == SubstFTy->getParameters ().size () - 1 )
973
992
removedSelfParam = true ;
974
993
continue ;
@@ -2216,7 +2235,7 @@ prepareCallArguments(ApplySite AI, SILBuilder &Builder,
2216
2235
return true ;
2217
2236
}
2218
2237
2219
- if (ReInfo.isDroppedMetatypeArg (ArgIdx))
2238
+ if (ReInfo.isDroppedArgument (ArgIdx))
2220
2239
return true ;
2221
2240
2222
2241
// Handle arguments for formal parameters.
@@ -2738,7 +2757,7 @@ ReabstractionThunkGenerator::convertReabstractionThunkArguments(
2738
2757
unsigned numParams = OrigF->getLoweredFunctionType ()->getNumParameters ();
2739
2758
for (unsigned origParamIdx = 0 , specArgIdx = 0 ; origParamIdx < numParams; ++origParamIdx) {
2740
2759
unsigned origArgIdx = ReInfo.param2ArgIndex (origParamIdx);
2741
- if (ReInfo.isDroppedMetatypeArg (origArgIdx)) {
2760
+ if (ReInfo.isDroppedArgument (origArgIdx)) {
2742
2761
assert (origArgIdx >= ApplySite (OrigPAI).getCalleeArgIndexOfFirstAppliedArg () &&
2743
2762
" cannot drop metatype argument of not applied argument" );
2744
2763
continue ;
@@ -2862,14 +2881,22 @@ lookupOrCreatePrespecialization(SILOptFunctionBuilder &funcBuilder,
2862
2881
return declaration;
2863
2882
}
2864
2883
2865
- bool usePrespecialized (
2884
+ static bool usePrespecialized (
2866
2885
SILOptFunctionBuilder &funcBuilder, ApplySite apply, SILFunction *refF,
2867
- const ReabstractionInfo &specializedReInfo,
2868
2886
ReabstractionInfo &prespecializedReInfo, SpecializedFunction &result) {
2869
2887
2888
+ if (refF->getSpecializeAttrs ().empty ())
2889
+ return false ;
2890
+
2870
2891
SmallVector<std::tuple<unsigned , ReabstractionInfo, AvailabilityContext>, 4 >
2871
2892
layoutMatches;
2872
2893
2894
+ ReabstractionInfo specializedReInfo (funcBuilder.getModule ().getSwiftModule (),
2895
+ funcBuilder.getModule ().isWholeModule (), apply, refF,
2896
+ apply.getSubstitutionMap (), IsNotSerialized,
2897
+ /* ConvertIndirectToDirect=*/ true ,
2898
+ /* dropMetatypeArgs=*/ false );
2899
+
2873
2900
for (auto *SA : refF->getSpecializeAttrs ()) {
2874
2901
if (!SA->isExported ())
2875
2902
continue ;
@@ -3185,7 +3212,7 @@ void swift::trySpecializeApplyOfGeneric(
3185
3212
ReabstractionInfo prespecializedReInfo (FuncBuilder.getModule ());
3186
3213
bool replacePartialApplyWithoutReabstraction = false ;
3187
3214
3188
- if (usePrespecialized (FuncBuilder, Apply, RefF, ReInfo, prespecializedReInfo,
3215
+ if (usePrespecialized (FuncBuilder, Apply, RefF, prespecializedReInfo,
3189
3216
prespecializedF)) {
3190
3217
ReInfo = prespecializedReInfo;
3191
3218
}
@@ -3343,7 +3370,7 @@ void swift::trySpecializeApplyOfGeneric(
3343
3370
SmallVector<SILValue, 4 > Arguments;
3344
3371
for (auto &Op : PAI->getArgumentOperands ()) {
3345
3372
unsigned calleeArgIdx = ApplySite (PAI).getCalleeArgIndex (Op);
3346
- if (ReInfo.isDroppedMetatypeArg (calleeArgIdx))
3373
+ if (ReInfo.isDroppedArgument (calleeArgIdx))
3347
3374
continue ;
3348
3375
Arguments.push_back (Op.get ());
3349
3376
}
0 commit comments