diff --git a/SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift b/SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift index 233a22ac476a9..6cd09ef54cdb7 100644 --- a/SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift +++ b/SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift @@ -58,6 +58,10 @@ private func optimize(function: Function, _ context: FunctionPassContext) { switch instruction { case let apply as FullApplySite: inlineAndDevirtualize(apply: apply, context, simplifyCtxt) + case let mt as MetatypeInst: + if mt.isTriviallyDeadIgnoringDebugUses { + simplifyCtxt.erase(instructionIncludingDebugUses: mt) + } default: break } @@ -65,8 +69,6 @@ private func optimize(function: Function, _ context: FunctionPassContext) { _ = context.specializeApplies(in: function, isMandatory: true) - removeUnusedMetatypeInstructions(in: function, context) - // If this is a just specialized function, try to optimize copy_addr, etc. if context.optimizeMemoryAccesses(in: function) { _ = context.eliminateDeadAllocations(in: function) @@ -101,15 +103,6 @@ private func inlineAndDevirtualize(apply: FullApplySite, _ context: FunctionPass } } -private func removeUnusedMetatypeInstructions(in function: Function, _ context: FunctionPassContext) { - for inst in function.instructions { - if let mt = inst as? MetatypeInst, - mt.isTriviallyDeadIgnoringDebugUses { - context.erase(instructionIncludingDebugUses: mt) - } - } -} - private func shouldInline(apply: FullApplySite, callee: Function) -> Bool { if callee.isTransparent { return true diff --git a/include/swift/SIL/GenericSpecializationMangler.h b/include/swift/SIL/GenericSpecializationMangler.h index ade99ce92c417..30a7543ff195b 100644 --- a/include/swift/SIL/GenericSpecializationMangler.h +++ b/include/swift/SIL/GenericSpecializationMangler.h @@ -88,8 +88,7 @@ class GenericSpecializationMangler : public SpecializationMangler { : SpecializationMangler(SpecializationPass::GenericSpecializer, Serialized, F) {} - std::string mangleNotReabstracted(SubstitutionMap subs, - bool metatyeParamsRemoved); + std::string mangleNotReabstracted(SubstitutionMap subs); /// Mangle a generic specialization with re-abstracted parameters. /// diff --git a/include/swift/SILOptimizer/Utils/Generics.h b/include/swift/SILOptimizer/Utils/Generics.h index b08750fec9608..90f7b97b072f8 100644 --- a/include/swift/SILOptimizer/Utils/Generics.h +++ b/include/swift/SILOptimizer/Utils/Generics.h @@ -157,6 +157,10 @@ class ReabstractionInfo { LoadableAndTrivial }; + unsigned param2ArgIndex(unsigned ParamIdx) const { + return ParamIdx + NumFormalIndirectResults; + } + // Create a new substituted type with the updated signature. CanSILFunctionType createSubstitutedType(SILFunction *OrigF, SubstitutionMap SubstMap, @@ -195,8 +199,8 @@ class ReabstractionInfo { ApplySite Apply, SILFunction *Callee, SubstitutionMap ParamSubs, IsSerialized_t Serialized, - bool ConvertIndirectToDirect, - bool dropMetatypeArgs, + bool ConvertIndirectToDirect = true, + bool dropMetatypeArgs = false, OptRemark::Emitter *ORE = nullptr); /// Constructs the ReabstractionInfo for generic function \p Callee with @@ -210,11 +214,7 @@ class ReabstractionInfo { IsSerialized_t isSerialized() const { return Serialized; } - - unsigned param2ArgIndex(unsigned ParamIdx) const { - return ParamIdx + NumFormalIndirectResults; - } - + /// Returns true if the specialized function needs an alternative mangling. /// See hasConvertedResilientParams. bool needAlternativeMangling() const { @@ -314,8 +314,6 @@ class ReabstractionInfo { CanSILFunctionType createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const; - CanSILFunctionType createThunkType(PartialApplyInst *forPAI) const; - SILFunction *getNonSpecializedFunction() const { return Callee; } /// Map type into a context of the specialized function. diff --git a/lib/SIL/Utils/GenericSpecializationMangler.cpp b/lib/SIL/Utils/GenericSpecializationMangler.cpp index 8dbc746d31ca7..6bcacf4242701 100644 --- a/lib/SIL/Utils/GenericSpecializationMangler.cpp +++ b/lib/SIL/Utils/GenericSpecializationMangler.cpp @@ -100,15 +100,10 @@ manglePrespecialized(GenericSignature sig, SubstitutionMap subs) { } std::string GenericSpecializationMangler:: -mangleNotReabstracted(SubstitutionMap subs, - bool metatyeParamsRemoved) { +mangleNotReabstracted(SubstitutionMap subs) { beginMangling(); appendSubstitutions(getGenericSignature(), subs); - if (metatyeParamsRemoved) { - appendSpecializationOperator("TGm"); - } else { - appendSpecializationOperator("TG"); - } + appendSpecializationOperator("TG"); return finalize(); } diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp index a0b98715a3a43..6d67536fbca4e 100644 --- a/lib/SILOptimizer/IPO/CapturePropagation.cpp +++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp @@ -492,7 +492,7 @@ static SILFunction *getSpecializedWithDeadParams( FuncBuilder.getModule().getSwiftModule(), FuncBuilder.getModule().isWholeModule(), ApplySite(), Specialized, PAI->getSubstitutionMap(), Specialized->isSerialized(), - /* ConvertIndirectToDirect */ false, /*dropMetatypeArgs=*/ false); + /* ConvertIndirectToDirect */ false); GenericFuncSpecializer FuncSpecializer(FuncBuilder, Specialized, ReInfo.getClonerParamSubstitutionMap(), diff --git a/lib/SILOptimizer/IPO/UsePrespecialized.cpp b/lib/SILOptimizer/IPO/UsePrespecialized.cpp index 3bec378550003..3ef4c899b70c9 100644 --- a/lib/SILOptimizer/IPO/UsePrespecialized.cpp +++ b/lib/SILOptimizer/IPO/UsePrespecialized.cpp @@ -91,9 +91,7 @@ bool UsePrespecialized::replaceByPrespecialized(SILFunction &F) { continue; ReabstractionInfo ReInfo(M.getSwiftModule(), M.isWholeModule(), AI, - ReferencedF, Subs, IsNotSerialized, - /*ConvertIndirectToDirect=*/ true, - /*dropMetatypeArgs=*/ false); + ReferencedF, Subs, IsNotSerialized); if (!ReInfo.canBeSpecialized()) continue; diff --git a/lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp b/lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp index 43b5e853cd98a..04c50546ccf65 100644 --- a/lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp +++ b/lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp @@ -217,8 +217,6 @@ bool PerformanceDiagnostics::checkClosureValue(SILValue closure, closure = tfi->getOperand(); } else if (auto *cp = dyn_cast(closure)) { closure = cp->getOperand(); - } else if (auto *cv = dyn_cast(closure)) { - closure = cv->getOperand(); } else if (acceptFunctionArgs && isa(closure)) { // We can assume that a function closure argument is already checked at // the call site. diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index c1f5dbbc230f5..ae5d6d62af8ac 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -997,35 +997,6 @@ ReabstractionInfo::createSubstitutedType(SILFunction *OrigF, return NewFnTy; } -CanSILFunctionType ReabstractionInfo::createThunkType(PartialApplyInst *forPAI) const { - if (!hasDroppedMetatypeArgs()) - return SubstitutedType; - - llvm::SmallVector newParams; - auto params = SubstitutedType->getParameters(); - unsigned firstAppliedParamIdx = params.size() - forPAI->getArguments().size(); - - for (unsigned paramIdx = 0; paramIdx < params.size(); ++paramIdx) { - if (paramIdx >= firstAppliedParamIdx && isDroppedMetatypeArg(param2ArgIndex(paramIdx))) - continue; - newParams.push_back(params[paramIdx]); - } - - auto newFnTy = SILFunctionType::get( - SubstitutedType->getInvocationGenericSignature(), - SubstitutedType->getExtInfo(), SubstitutedType->getCoroutineKind(), - SubstitutedType->getCalleeConvention(), newParams, - SubstitutedType->getYields(), SubstitutedType->getResults(), - SubstitutedType->getOptionalErrorResult(), - SubstitutedType->getPatternSubstitutions(), SubstitutionMap(), - SubstitutedType->getASTContext(), - SubstitutedType->getWitnessMethodConformanceOrInvalid()); - - // This is an interface type. It should not have any archetypes. - assert(!newFnTy->hasArchetype()); - return newFnTy; -} - /// Convert the substituted function type into a specialized function type based /// on the ReabstractionInfo. CanSILFunctionType ReabstractionInfo:: @@ -1096,10 +1067,8 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const { : CanGenericSignature(); SILFunctionType::ExtInfo extInfo = SubstFTy->getExtInfo(); - ProtocolConformanceRef conf = SubstFTy->getWitnessMethodConformanceOrInvalid(); if (extInfo.hasSelfParam() && removedSelfParam) { extInfo = extInfo.withRepresentation(SILFunctionTypeRepresentation::Thin); - conf = ProtocolConformanceRef(); assert(!extInfo.hasSelfParam()); } @@ -1108,7 +1077,7 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const { SubstFTy->getCoroutineKind(), SubstFTy->getCalleeConvention(), SpecializedParams, SpecializedYields, SpecializedResults, SubstFTy->getOptionalErrorResult(), SubstitutionMap(), SubstitutionMap(), - M.getASTContext(), conf); + M.getASTContext(), SubstFTy->getWitnessMethodConformanceOrInvalid()); } /// Create a new generic signature from an existing one by adding @@ -2562,8 +2531,7 @@ class ReabstractionThunkGenerator { if (!ReInfo.isPartialSpecialization()) { Mangle::GenericSpecializationMangler Mangler(OrigF, ReInfo.isSerialized()); ThunkName = Mangler.mangleNotReabstracted( - ReInfo.getCalleeParamSubstitutionMap(), - ReInfo.hasDroppedMetatypeArgs()); + ReInfo.getCalleeParamSubstitutionMap()); } else { Mangle::PartialSpecializationMangler Mangler( OrigF, ReInfo.getSpecializedType(), ReInfo.isSerialized(), @@ -2578,16 +2546,14 @@ class ReabstractionThunkGenerator { protected: FullApplySite createReabstractionThunkApply(SILBuilder &Builder); SILArgument *convertReabstractionThunkArguments( - SILBuilder &Builder, SmallVectorImpl &ArgsNeedingEndBorrows, - CanSILFunctionType thunkType); + SILBuilder &Builder, SmallVectorImpl &ArgsNeedingEndBorrows); }; } // anonymous namespace SILFunction *ReabstractionThunkGenerator::createThunk() { - CanSILFunctionType thunkType = ReInfo.createThunkType(OrigPAI); SILFunction *Thunk = FunctionBuilder.getOrCreateSharedFunction( - Loc, ThunkName, thunkType, IsBare, IsTransparent, + Loc, ThunkName, ReInfo.getSubstitutedType(), IsBare, IsTransparent, ReInfo.isSerialized(), ProfileCounter(), IsThunk, IsNotDynamic, IsNotDistributed, IsNotRuntimeAccessible); // Re-use an existing thunk. @@ -2628,7 +2594,7 @@ SILFunction *ReabstractionThunkGenerator::createThunk() { // Handle lowered addresses. SmallVector ArgsThatNeedEndBorrow; SILArgument *ReturnValueAddr = - convertReabstractionThunkArguments(Builder, ArgsThatNeedEndBorrow, thunkType); + convertReabstractionThunkArguments(Builder, ArgsThatNeedEndBorrow); FullApplySite ApplySite = createReabstractionThunkApply(Builder); @@ -2684,18 +2650,6 @@ FullApplySite ReabstractionThunkGenerator::createReabstractionThunkApply( return FullApplySite(TAI); } -static SILFunctionArgument *addFunctionArgument(SILFunction *function, - SILType argType, - SILArgument *copyAttributesFrom) { - SILBasicBlock *entryBB = function->getEntryBlock(); - auto *src = cast(copyAttributesFrom); - auto *arg = entryBB->createFunctionArgument(argType, src->getDecl()); - arg->setNoImplicitCopy(src->isNoImplicitCopy()); - arg->setLifetimeAnnotation(src->getLifetimeAnnotation()); - arg->setClosureCapture(src->isClosureCapture()); - return arg; -} - /// Create SIL arguments for a reabstraction thunk with lowered addresses. This /// may involve replacing indirect arguments with loads and stores. Return the /// SILArgument for the address of an indirect result, or nullptr. @@ -2703,31 +2657,43 @@ static SILFunctionArgument *addFunctionArgument(SILFunction *function, /// FIXME: Remove this if we don't need to create reabstraction thunks after /// address lowering. SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments( - SILBuilder &Builder, SmallVectorImpl &ArgsThatNeedEndBorrow, - CanSILFunctionType thunkType -) { + SILBuilder &Builder, SmallVectorImpl &ArgsThatNeedEndBorrow) { SILFunction *Thunk = &Builder.getFunction(); CanSILFunctionType SpecType = SpecializedFunc->getLoweredFunctionType(); + CanSILFunctionType SubstType = ReInfo.getSubstitutedType(); auto specConv = SpecializedFunc->getConventions(); (void)specConv; - SILFunctionConventions substConv(thunkType, M); + SILFunctionConventions substConv(SubstType, M); assert(specConv.useLoweredAddresses()); // ReInfo.NumIndirectResults corresponds to SubstTy's formal indirect // results. SpecTy may have fewer formal indirect results. - assert(thunkType->getNumIndirectFormalResults() + assert(SubstType->getNumIndirectFormalResults() >= SpecType->getNumIndirectFormalResults()); + SILBasicBlock *EntryBB = Thunk->getEntryBlock(); SILArgument *ReturnValueAddr = nullptr; auto SpecArgIter = SpecializedFunc->getArguments().begin(); - + auto cloneSpecializedArgument = [&]() { + // No change to the argument. + SILArgument *SpecArg = *SpecArgIter++; + auto *NewArg = + EntryBB->createFunctionArgument(SpecArg->getType(), SpecArg->getDecl()); + NewArg->setNoImplicitCopy( + cast(SpecArg)->isNoImplicitCopy()); + NewArg->setLifetimeAnnotation( + cast(SpecArg)->getLifetimeAnnotation()); + NewArg->setClosureCapture( + cast(SpecArg)->isClosureCapture()); + Arguments.push_back(NewArg); + }; // ReInfo.NumIndirectResults corresponds to SubstTy's formal indirect // results. SpecTy may have fewer formal indirect results. - assert(thunkType->getNumIndirectFormalResults() + assert(SubstType->getNumIndirectFormalResults() >= SpecType->getNumIndirectFormalResults()); unsigned resultIdx = 0; - for (auto substRI : thunkType->getIndirectFormalResults()) { + for (auto substRI : SubstType->getIndirectFormalResults()) { if (ReInfo.isFormalResultConverted(resultIdx++)) { // Convert an originally indirect to direct specialized result. // Store the result later. @@ -2737,35 +2703,36 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments( substConv.getSILType(substRI, Builder.getTypeExpansionContext())); assert(ResultTy.isAddress()); assert(!ReturnValueAddr); - ReturnValueAddr = Thunk->getEntryBlock()->createFunctionArgument(ResultTy); + ReturnValueAddr = EntryBB->createFunctionArgument(ResultTy); continue; } // If the specialized result is already indirect, simply clone the indirect // result argument. - SILArgument *specArg = *SpecArgIter++; - assert(specArg->getType().isAddress()); - Arguments.push_back(addFunctionArgument(Thunk, specArg->getType(), specArg)); + assert((*SpecArgIter)->getType().isAddress()); + cloneSpecializedArgument(); } assert(SpecArgIter == SpecializedFunc->getArgumentsWithoutIndirectResults().begin()); - unsigned numParams = OrigF->getLoweredFunctionType()->getNumParameters(); - for (unsigned origParamIdx = 0, specArgIdx = 0; origParamIdx < numParams; ++origParamIdx) { - unsigned origArgIdx = ReInfo.param2ArgIndex(origParamIdx); - if (ReInfo.isDroppedMetatypeArg(origArgIdx)) { - assert(origArgIdx >= ApplySite(OrigPAI).getCalleeArgIndexOfFirstAppliedArg() && - "cannot drop metatype argument of not applied argument"); - continue; - } - SILArgument *specArg = *SpecArgIter++; - if (ReInfo.isParamConverted(origParamIdx)) { + unsigned numParams = SpecType->getNumParameters(); + assert(numParams == SubstType->getNumParameters()); + for (unsigned paramIdx = 0; paramIdx < numParams; ++paramIdx) { + if (ReInfo.isParamConverted(paramIdx)) { // Convert an originally indirect to direct specialized parameter. - assert(!specConv.isSILIndirect(SpecType->getParameters()[specArgIdx])); + assert(!specConv.isSILIndirect(SpecType->getParameters()[paramIdx])); // Instead of passing the address, pass the loaded value. SILType ParamTy = SpecializedFunc->mapTypeIntoContext( - substConv.getSILType(thunkType->getParameters()[specArgIdx], + substConv.getSILType(SubstType->getParameters()[paramIdx], Builder.getTypeExpansionContext())); assert(ParamTy.isAddress()); - SILFunctionArgument *NewArg = addFunctionArgument(Thunk, ParamTy, specArg); + SILArgument *SpecArg = *SpecArgIter++; + SILFunctionArgument *NewArg = + EntryBB->createFunctionArgument(ParamTy, SpecArg->getDecl()); + NewArg->setNoImplicitCopy( + cast(SpecArg)->isNoImplicitCopy()); + NewArg->setLifetimeAnnotation( + cast(SpecArg)->getLifetimeAnnotation()); + NewArg->setClosureCapture( + cast(SpecArg)->isClosureCapture()); if (!NewArg->getArgumentConvention().isGuaranteedConvention()) { SILValue argVal = Builder.emitLoadValueOperation( Loc, NewArg, LoadOwnershipQualifier::Take); @@ -2776,11 +2743,10 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments( ArgsThatNeedEndBorrow.push_back(Arguments.size()); Arguments.push_back(argVal); } - } else { - // Simply clone unconverted direct or indirect parameters. - Arguments.push_back(addFunctionArgument(Thunk, specArg->getType(), specArg)); + continue; } - ++specArgIdx; + // Simply clone unconverted direct or indirect parameters. + cloneSpecializedArgument(); } assert(SpecArgIter == SpecializedFunc->getArguments().end()); return ReturnValueAddr; @@ -2807,7 +2773,7 @@ static bool createPrespecialized(StringRef UnspecializedName, ReabstractionInfo ReInfo(M.getSwiftModule(), M.isWholeModule(), ApplySite(), UnspecFunc, Apply.getSubstitutionMap(), IsNotSerialized, - /*ConvertIndirectToDirect= */true, /*dropMetatypeArgs=*/ false); + /*ConvertIndirectToDirect=*/true); if (!ReInfo.canBeSpecialized()) return false; @@ -2979,7 +2945,7 @@ bool usePrespecialized( funcBuilder.getModule().getSwiftModule(), funcBuilder.getModule().isWholeModule(), apply, refF, newSubstMap, apply.getFunction()->isSerialized() ? IsSerialized : IsNotSerialized, - /*ConvertIndirectToDirect=*/ true, /*dropMetatypeArgs=*/ false, nullptr); + /*ConvertIndirectToDirect=*/true, /*dropMetatypeArgs*/true, nullptr); if (layoutReInfo.getSpecializedType() == reInfo.getSpecializedType()) { layoutMatches.push_back( @@ -3039,54 +3005,6 @@ bool usePrespecialized( return false; } -static bool isUsedAsDynamicSelf(SILArgument *arg) { - for (Operand *use : arg->getUses()) { - if (use->isTypeDependent()) - return true; - } - return false; -} - -static bool canDropMetatypeArgs(ApplySite apply, SILFunction *callee) { - if (!callee->isDefinition()) - return false; - - auto calleeArgs = callee->getArguments(); - unsigned firstAppliedArgIdx = apply.getCalleeArgIndexOfFirstAppliedArg(); - for (unsigned calleeArgIdx = 0; calleeArgIdx < calleeArgs.size(); ++calleeArgIdx) { - SILArgument *calleeArg = calleeArgs[calleeArgIdx]; - auto mt = calleeArg->getType().getAs(); - if (!mt) - continue; - - if (isUsedAsDynamicSelf(calleeArg)) - return false; - - // We don't drop metatype arguments of not applied arguments (in case of `partial_apply`). - if (firstAppliedArgIdx > calleeArgIdx) - return false; - - if (mt->hasRepresentation() && mt->getRepresentation() == MetatypeRepresentation::Thin) - continue; - - // If the passed thick metatype value is not a `metatype` instruction - // we don't know the real metatype at runtime. It's not necessarily the - // same as the declared metatype. It could e.g. be an upcast of a class - // metatype. - SILValue callerArg = apply.getArguments()[calleeArgIdx - firstAppliedArgIdx]; - if (isa(callerArg)) - continue; - - // But: if the metatype is not used in the callee we don't have to care - // what metatype value is passed. We can just remove it. - if (callee->isDefinition() && onlyHaveDebugUses(calleeArg)) - continue; - - return false; - } - return true; -} - void swift::trySpecializeApplyOfGeneric( SILOptFunctionBuilder &FuncBuilder, ApplySite Apply, DeadInstructionSet &DeadApplies, @@ -3135,7 +3053,7 @@ void swift::trySpecializeApplyOfGeneric( FuncBuilder.getModule().isWholeModule(), Apply, RefF, Apply.getSubstitutionMap(), Serialized, /*ConvertIndirectToDirect=*/ true, - /*dropMetatypeArgs=*/ canDropMetatypeArgs(Apply, RefF), + /*dropMetatypeArgs=*/ isMandatory, &ORE); if (!ReInfo.canBeSpecialized()) return; @@ -3292,19 +3210,16 @@ void swift::trySpecializeApplyOfGeneric( auto *FRI = Builder.createFunctionRef(PAI->getLoc(), Thunk); SmallVector Arguments; for (auto &Op : PAI->getArgumentOperands()) { - unsigned calleeArgIdx = ApplySite(PAI).getCalleeArgIndex(Op); - if (ReInfo.isDroppedMetatypeArg(calleeArgIdx)) - continue; Arguments.push_back(Op.get()); } auto Subs = ReInfo.getCallerParamSubstitutionMap(); auto FnTy = Thunk->getLoweredFunctionType(); Subs = SubstitutionMap::get(FnTy->getSubstGenericSignature(), Subs); - SingleValueInstruction *newPAI = Builder.createPartialApply( - PAI->getLoc(), FRI, Subs, Arguments, - PAI->getType().getAs()->getCalleeConvention(), - PAI->isOnStack()); - PAI->replaceAllUsesWith(newPAI); + auto *NewPAI = Builder.createPartialApply( + PAI->getLoc(), FRI, Subs, Arguments, + PAI->getType().getAs()->getCalleeConvention(), + PAI->isOnStack()); + PAI->replaceAllUsesWith(NewPAI); DeadApplies.insert(PAI); return; } diff --git a/test/SIL/Serialization/specializer_can_deserialize.swift b/test/SIL/Serialization/specializer_can_deserialize.swift index c37e86c8babd4..bd60c0f440c40 100644 --- a/test/SIL/Serialization/specializer_can_deserialize.swift +++ b/test/SIL/Serialization/specializer_can_deserialize.swift @@ -8,10 +8,10 @@ import Swift // CHECK-LABEL: sil {{.*}}@main // CHECK: bb0({{.*}}): -// CHECK: function_ref @$ss9ContainerVAByxGycfCBi32__Tgm5{{.*}} +// CHECK: function_ref @$ss9ContainerVAByxGycfCBi32__Tg5{{.*}} // CHECK: function_ref @$ss9ContainerV11doSomethingyyFBi32__Tg5{{.*}} -// CHECK-LABEL: sil shared [noinline] @$ss9ContainerVAByxGycfCBi32__Tgm5 +// CHECK-LABEL: sil shared [noinline] @$ss9ContainerVAByxGycfCBi32__Tg5Tf4d_n // CHECK-LABEL: sil shared [noinline] @$ss9ContainerV11doSomethingyyFBi32__Tg5Tf4d_n diff --git a/test/SILOptimizer/existential_metatype.swift b/test/SILOptimizer/existential_metatype.swift index b6dcdb4f7bbe0..bd599b48e753e 100644 --- a/test/SILOptimizer/existential_metatype.swift +++ b/test/SILOptimizer/existential_metatype.swift @@ -3,12 +3,12 @@ protocol SomeP {} public enum SpecialEnum : SomeP {} -// CHECK-LABEL: sil shared [noinline] @$s20existential_metatype17checkProtocolType0aE0Sbxm_tAA5SomePRzlFAA11SpecialEnumO_Tgm5 : $@convention(thin) () -> Bool { +// CHECK-LABEL: sil shared [noinline] @$s20existential_metatype17checkProtocolType0aE0Sbxm_tAA5SomePRzlFAA11SpecialEnumO_Tg5Tf4d_n : $@convention(thin) () -> Bool { // CHECK: bb0: // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool (%0 : $Builtin.Int1) // CHECK-NEXT: return %1 : $Bool -// CHECK-LABEL: } // end sil function '$s20existential_metatype17checkProtocolType0aE0Sbxm_tAA5SomePRzlFAA11SpecialEnumO_Tgm5' +// CHECK-LABEL: } // end sil function '$s20existential_metatype17checkProtocolType0aE0Sbxm_tAA5SomePRzlFAA11SpecialEnumO_Tg5Tf4d_n' @inline(never) func checkProtocolType

(existentialType: P.Type) -> Bool { return existentialType == SpecialEnum.self diff --git a/test/SILOptimizer/performance-annotations.swift b/test/SILOptimizer/performance-annotations.swift index d7eb09eecd7a8..6954d4a09ca79 100644 --- a/test/SILOptimizer/performance-annotations.swift +++ b/test/SILOptimizer/performance-annotations.swift @@ -272,33 +272,3 @@ func testGlobalsWithConversion() -> UInt32 { return globalB } -public struct X: Collection { - public func index(after i: Int) -> Int { - return i + 1 - } - public subscript(position: Int) -> Int { - get { - return 0 - } - } - public var startIndex: Int = 0 - public var endIndex: Int = 1 - public typealias Index = Int -} - -extension Collection where Element: Comparable { - public func testSorted() -> Int { - return testSorted(by: <) - } - public func testSorted(by areInIncreasingOrder: (Element, Element) -> Bool) -> Int { - let x = 0 - _ = areInIncreasingOrder(self.first!, self.first!) - return x - } -} -@_noLocks -public func testCollectionSort(a: X) -> Int { - _ = a.testSorted() - return 0 -} - diff --git a/test/SILOptimizer/set.swift b/test/SILOptimizer/set.swift index ff9b345c373ad..b69048e8d04dc 100644 --- a/test/SILOptimizer/set.swift +++ b/test/SILOptimizer/set.swift @@ -23,7 +23,7 @@ public func createEmptySetWithInitializer() -> Set { // CHECK-LABEL: sil {{.*}}@$s4test17createNonEmptySetShySiGyF // CHECK: global_value -// CHECK: [[F:%[0-9]+]] = function_ref @$sSh21_nonEmptyArrayLiteralShyxGSayxG_tcfCSi_Tgm5 +// CHECK: [[F:%[0-9]+]] = function_ref @$sSh21_nonEmptyArrayLiteralShyxGSayxG_tcfCSi_Tg5 // CHECK: apply [[F]] // CHECK: } // end sil function '$s4test17createNonEmptySetShySiGyF' public func createNonEmptySet() -> Set { diff --git a/test/SILOptimizer/specialize.sil b/test/SILOptimizer/specialize.sil index ae848e7935408..ce616d250728d 100644 --- a/test/SILOptimizer/specialize.sil +++ b/test/SILOptimizer/specialize.sil @@ -9,7 +9,7 @@ import Swift // CHECK-LABEL: sil @exp1 : $@convention(thin) () -> () { // CHECK-NOT: apply // Call of specialized initializer: -// CHECK: [[CTOR:%[0-9]+]] = function_ref @$s8XXX_inits5Int32V_Tgm5 +// CHECK: [[CTOR:%[0-9]+]] = function_ref @$s8XXX_inits5Int32V_Tg5 // CHECK: apply [[CTOR]] // CHECK: [[ACCEPTS_INT:%[0-9]+]] = function_ref @acceptsInt // Call of specialized XXX_foo: @@ -35,7 +35,7 @@ import Swift // YAML: Line: 73 // YAML: Column: 17 // YAML-NEXT: - String: ' with type ' -// YAML-NEXT: - FuncType: '(Int32) -> XXX' +// YAML-NEXT: - FuncType: '(Int32, @thin XXX.Type) -> XXX' // YAML-NEXT: ... // YAML-NEXT: --- !Passed // YAML-NEXT: Pass: sil-generic-specializer @@ -556,7 +556,7 @@ bb0: // test_bind (Builtin.RawPointer, A.Type) -> () // Check that this is specialized as T=Int. -// CHECK-LABEL: sil shared @$s9test_bindSi_Tgm5 : $@convention(thin) (Builtin.RawPointer) -> () +// CHECK-LABEL: sil shared @$s9test_bindSi_Tg5 : $@convention(thin) (Builtin.RawPointer, @thick Int.Type) -> () // CHECK: bind_memory %0 : $Builtin.RawPointer, {{%.*}} : $Builtin.Word to $*Int // CHECK: return sil hidden @test_bind : $@convention(thin) (Builtin.RawPointer, @thick T.Type) -> () { @@ -701,7 +701,7 @@ bb0(%0 : $*T, %1 :$*T): } // This should not assert. -// CHECK-LABEL: sil shared @$s26specialize_no_return_applys5NeverO_Tgm5 +// CHECK-LABEL: sil shared @$s26specialize_no_return_applys5NeverO_Tg5 // CHECK: apply // CHECK-NEXT: unreachable diff --git a/test/SILOptimizer/specialize_chain.swift b/test/SILOptimizer/specialize_chain.swift index 2b16ec0721a4f..4616ee73fa4d2 100644 --- a/test/SILOptimizer/specialize_chain.swift +++ b/test/SILOptimizer/specialize_chain.swift @@ -45,6 +45,6 @@ func exp1() { //CHECK: sil shared [noinline] @$s16specialize_chain3YYYV4AAA2{{[_0-9a-zA-Z]*}}FSi_Tg5 //CHECK: sil shared [noinline] @$s16specialize_chain3YYYV4AAA1{{[_0-9a-zA-Z]*}}FSi_Tg5 //CHECK: exp1 -//CHECK: function_ref @$s16specialize_chain3YYYV{{[_0-9a-zA-Z]*}}fCSi_Tgm5 +//CHECK: function_ref @$s16specialize_chain3YYYV{{[_0-9a-zA-Z]*}}fCSi_Tg5 //CHECK: function_ref @$s16specialize_chain3YYYV4AAA9{{[_0-9a-zA-Z]*}}FSi_Tg5 //CHECK: return diff --git a/test/SILOptimizer/specialize_ossa.sil b/test/SILOptimizer/specialize_ossa.sil index b7f59edffac5d..38ae45baed1d8 100644 --- a/test/SILOptimizer/specialize_ossa.sil +++ b/test/SILOptimizer/specialize_ossa.sil @@ -6,7 +6,6 @@ import Builtin import Swift class Klass {} -class GenericKlass {} sil [ossa] [transparent] @ossaTransparentCallee : $@convention(thin) (@in T) -> () { bb0(%0 : $*T): @@ -44,7 +43,7 @@ bb0(%0 : $Builtin.NativeObject): // CHECK-LABEL: sil [ossa] @exp1 : $@convention(thin) () -> () { // CHECK-NOT: apply // Call of specialized initializer: -// CHECK: [[CTOR:%[0-9]+]] = function_ref @$s8XXX_inits5Int32V_Tgm5 +// CHECK: [[CTOR:%[0-9]+]] = function_ref @$s8XXX_inits5Int32V_Tg5 // CHECK: apply [[CTOR]] // CHECK: [[ACCEPTS_INT:%[0-9]+]] = function_ref @acceptsInt // Call of specialized XXX_foo: @@ -635,7 +634,7 @@ bb0: // test_bind (Builtin.RawPointer, A.Type) -> () // Check that this is specialized as T=Int. -// CHECK-LABEL: sil shared [ossa] @$s9test_bindSi_Tgm5 : $@convention(thin) (Builtin.RawPointer) -> () { +// CHECK-LABEL: sil shared [ossa] @$s9test_bindSi_Tg5 : $@convention(thin) (Builtin.RawPointer, @thick Int.Type) -> () // CHECK: bind_memory %0 : $Builtin.RawPointer, {{%.*}} : $Builtin.Word to $*Int // CHECK: return sil hidden [ossa] @test_bind : $@convention(thin) (Builtin.RawPointer, @thick T.Type) -> () { @@ -894,7 +893,7 @@ bb0(%0 : $*T, %1 :$*T): } // This should not assert. -// CHECK-LABEL: sil shared [ossa] @$s26specialize_no_return_applys5NeverO_Tgm5 : $@convention(thin) () -> () { +// CHECK-LABEL: sil shared [ossa] @$s26specialize_no_return_applys5NeverO_Tg5 // CHECK: apply // CHECK-NEXT: unreachable @@ -1306,7 +1305,7 @@ sil @genericReturn : $@convention(thin) <τ_0_0> (@guaranteed AnyObject) -> @out // The generic cloner needs to be able to compute liveness to fixup a // store borrow scope when the only use is in unreachable code. // specialized testNoReturnSpecialization -// CHECK-LABEL: sil shared [ossa] @$s26testNoReturnSpecializations5NeverO_Tgm5 : $@convention(thin) (@guaranteed AnyObject) -> () { +// CHECK-LABEL: sil shared [ossa] @$s26testNoReturnSpecializations5NeverO_Tg5 : $@convention(thin) (@guaranteed AnyObject, @thick Never.Type) -> () { // CHECK: [[SB:%.*]] = store_borrow %0 to %{{.*}} : $*AnyObject // CHECK: [[LB:%.*]] = load_borrow [[SB]] : $*AnyObject // CHECK: apply %{{.*}}(%{{.*}}, [[LB]]) : $@convention(thin) <τ_0_0> (@guaranteed AnyObject) -> @out τ_0_0 @@ -1315,7 +1314,7 @@ sil @genericReturn : $@convention(thin) <τ_0_0> (@guaranteed AnyObject) -> @out // CHECK: bb1: // CHECK: end_borrow [[LB]] : $AnyObject // CHECK: end_borrow [[SB]] : $*AnyObject -// CHECK-LABEL: } // end sil function '$s26testNoReturnSpecializations5NeverO_Tgm5' +// CHECK-LABEL: } // end sil function '$s26testNoReturnSpecializations5NeverO_Tg5' sil [ossa] @testNoReturnSpecialization : $@convention(thin) (@in_guaranteed AnyObject, @thick T.Type) -> () { bb0(%0 : $*AnyObject, %1 : $@thick T.Type): %2 = load_borrow %0 : $*AnyObject @@ -1337,132 +1336,3 @@ bb0(%0 : $*AnyObject): %t = tuple () return %t : $() } - -sil [ossa] @metatypeUsed : $@convention(thin) (@thick GenericKlass.Type) -> () { -bb0(%0 : $@thick GenericKlass.Type): - %1 = alloc_ref_dynamic %0 : $@thick GenericKlass.Type, $GenericKlass - destroy_value %1 : $GenericKlass - %3 = tuple () - return %3 : $() -} - -sil [ossa] @metatypeUnused : $@convention(thin) (@thick GenericKlass.Type) -> () { -bb0(%0 : $@thick GenericKlass.Type): - debug_value %0 : $@thick GenericKlass.Type, let, name "mt", argno 0 - %2 = tuple () - return %2 : $() -} - -// CHECK-LABEL: sil [ossa] @callUsedMetatypeWithConcreteMetatype : -// CHECK: = function_ref @$s12metatypeUsedSi_Tgm5 : $@convention(thin) () -> () -// CHECK-LABEL: } // end sil function 'callUsedMetatypeWithConcreteMetatype' -sil [ossa] @callUsedMetatypeWithConcreteMetatype : $@convention(thin) () -> () { -bb0: - %0 = metatype $@thick GenericKlass.Type - %1 = function_ref @metatypeUsed : $@convention(thin) (@thick GenericKlass.Type) -> () - %2 = apply %1(%0) : $@convention(thin) (@thick GenericKlass.Type) -> () - %3 = tuple () - return %3 : $() -} - -// CHECK-LABEL: sil [ossa] @callUsedMetatypeWithUnknownMetatype : -// CHECK: = function_ref @$s12metatypeUsedSi_Tg5 : $@convention(thin) (@thick GenericKlass.Type) -> () -// CHECK-LABEL: } // end sil function 'callUsedMetatypeWithUnknownMetatype' -sil [ossa] @callUsedMetatypeWithUnknownMetatype : $@convention(thin) (@thick GenericKlass.Type) -> () { -bb0(%0 : $@thick GenericKlass.Type): - %1 = function_ref @metatypeUsed : $@convention(thin) (@thick GenericKlass.Type) -> () - %2 = apply %1(%0) : $@convention(thin) (@thick GenericKlass.Type) -> () - %3 = tuple () - return %3 : $() -} - -// CHECK-LABEL: sil [ossa] @callUnusedMetatypeWithUnknownMetatype : -// CHECK: = function_ref @$s14metatypeUnusedSi_Tgm5 : $@convention(thin) () -> () -// CHECK-LABEL: } // end sil function 'callUnusedMetatypeWithUnknownMetatype' -sil [ossa] @callUnusedMetatypeWithUnknownMetatype : $@convention(thin) (@thick GenericKlass.Type) -> () { -bb0(%0 : $@thick GenericKlass.Type): - %1 = function_ref @metatypeUnused : $@convention(thin) (@thick GenericKlass.Type) -> () - %2 = apply %1(%0) : $@convention(thin) (@thick GenericKlass.Type) -> () - %3 = tuple () - return %3 : $() -} - -sil [ossa] @closure_with_metatype : $@convention(thin) (@in_guaranteed T, @thick GenericKlass.Type) -> () { -bb0(%0 : $*T, %1 : $@thick GenericKlass.Type): - %3 = tuple () - return %3 : $() -} - -// CHECK-LABEL: sil [ossa] @returnClosureWithAppliedMetatype : -// CHECK: = function_ref @$s21closure_with_metatypeSi_TGm5 : $@convention(thin) (@in_guaranteed Int) -> () -// CHECK-LABEL: } // end sil function 'returnClosureWithAppliedMetatype' -sil [ossa] @returnClosureWithAppliedMetatype : $@convention(thin) () -> @owned @callee_owned (@in_guaranteed Int) -> () { -bb0: - %0 = metatype $@thick GenericKlass.Type - %1 = function_ref @closure_with_metatype : $@convention(thin) (@in_guaranteed T, @thick GenericKlass.Type) -> () - %2 = partial_apply %1(%0) : $@convention(thin) (@in_guaranteed T, @thick GenericKlass.Type) -> () - return %2 : $@callee_owned (@in_guaranteed Int) -> () -} - -// CHECK-LABEL: sil [ossa] @returnClosureWithNotAppliedMetatype : -// CHECK: = function_ref @$s21closure_with_metatypeSi_TG5 : $@convention(thin) (@in_guaranteed Int, @thick GenericKlass.Type) -> () -// CHECK-LABEL: } // end sil function 'returnClosureWithNotAppliedMetatype' -sil [ossa] @returnClosureWithNotAppliedMetatype : $@convention(thin) () -> @owned @callee_owned (@in_guaranteed Int, @thick GenericKlass.Type) -> () { -bb0: - %1 = function_ref @closure_with_metatype : $@convention(thin) (@in_guaranteed T, @thick GenericKlass.Type) -> () - %2 = partial_apply %1() : $@convention(thin) (@in_guaranteed T, @thick GenericKlass.Type) -> () - return %2 : $@callee_owned (@in_guaranteed Int, @thick GenericKlass.Type) -> () -} - -sil [ossa] @method_with_dynamic_self : $@convention(method) (@thick GenericKlass.Type) -> () { -bb0(%0 : $@thick GenericKlass.Type): - %1 = metatype $@thick @dynamic_self GenericKlass.Type - %2 = tuple () - return %2 : $() -} - -// CHECK-LABEL: sil [ossa] @callMethodWithDynamicSelf : -// CHECK: = function_ref @$s24method_with_dynamic_selfSi_Tg5 : $@convention(method) (@thick GenericKlass.Type) -> () -// CHECK-LABEL: } // end sil function 'callMethodWithDynamicSelf' -sil [ossa] @callMethodWithDynamicSelf : $@convention(thin) () -> () { -bb0: - %0 = metatype $@thick GenericKlass.Type - %1 = function_ref @method_with_dynamic_self : $@convention(method) (@thick GenericKlass.Type) -> () - %2 = apply %1(%0) : $@convention(method) (@thick GenericKlass.Type) -> () - return %2 : $() -} - -sil @complex_closure : $@convention(thin) (@thick T.Type, @in_guaranteed T, Bool) -> @out T { -bb0(%0 : $*T, %2 : $@thick T.Type, %3 : $*T, %4 : $Bool): - %5 = tuple () - return %5 : $() -} - -// CHECK-LABEL: sil [ossa] @returnComplexClosure : -// CHECK: = function_ref @$s15complex_closureSi_TGm5 : $@convention(thin) (@in_guaranteed Int, Bool) -> @out Int -// CHECK-LABEL: } // end sil function 'returnComplexClosure' -sil [ossa] @returnComplexClosure : $@convention(thin) (@in Int, Bool) -> @owned @callee_owned () -> @out Int { -bb0(%0: $*Int, %1 : $Bool): - %2 = metatype $@thick Int.Type - %3 = function_ref @complex_closure : $@convention(thin) (@thick T.Type, @in_guaranteed T, Bool) -> @out T - %4 = partial_apply %3(%2, %0, %1) : $@convention(thin) (@thick T.Type, @in_guaranteed T, Bool) -> @out T - return %4 : $@callee_owned () -> @out Int -} - -sil [ossa] @closure_with_thin_metatype : $@convention(thin) (@in_guaranteed T, @thin GenericKlass.Type) -> @out T { -bb0(%0 : $*T, %1 : $*T, %2 : $@thin GenericKlass.Type): - copy_addr %1 to [init] %0: $*T - %3 = tuple () - return %3 : $() -} - -// CHECK-LABEL: sil [ossa] @returnClosureWithNotAppliedThinMetatype : -// CHECK: = function_ref @$s26closure_with_thin_metatypeSi_TG5 : $@convention(thin) (@in_guaranteed Int, @thin GenericKlass.Type) -> @out Int -// CHECK-LABEL: } // end sil function 'returnClosureWithNotAppliedThinMetatype' -sil [ossa] @returnClosureWithNotAppliedThinMetatype : $@convention(thin) () -> @owned @callee_owned (@in_guaranteed Int, @thin GenericKlass.Type) -> @out Int { -bb0: - %1 = function_ref @closure_with_thin_metatype : $@convention(thin) (@in_guaranteed T, @thin GenericKlass.Type) -> @out T - %2 = partial_apply %1() : $@convention(thin) (@in_guaranteed T, @thin GenericKlass.Type) -> @out T - return %2 : $@callee_owned (@in_guaranteed Int, @thin GenericKlass.Type) -> @out Int -} - diff --git a/test/SILOptimizer/specialize_unconditional_checked_cast.swift b/test/SILOptimizer/specialize_unconditional_checked_cast.swift index b0449e8b6524c..d7b6728acd9c9 100644 --- a/test/SILOptimizer/specialize_unconditional_checked_cast.swift +++ b/test/SILOptimizer/specialize_unconditional_checked_cast.swift @@ -374,8 +374,8 @@ ExistentialToArchetype(o: o, t: o) // value cast. We could do the promotion, but the optimizer would need // to insert the Optional unwrapping logic before the cast. // -// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast15genericDownCastyq_x_q_mtr0_lFAA1CCSg_AA1DCTgm5 : $@convention(thin) (@guaranteed Optional) -> @owned D { -// CHECK: bb0(%0 : $Optional): +// CHECK-LABEL: sil shared [noinline] @$s37specialize_unconditional_checked_cast15genericDownCastyq_x_q_mtr0_lFAA1CCSg_AA1DCTg5 : $@convention(thin) (@guaranteed Optional, @thick D.Type) -> @owned D { +// CHECK: bb0(%0 : $Optional, %1 : $@thick D.Type): // CHECK-DAG: [[STACK_D:%[0-9]+]] = alloc_stack $D // CHECK-DAG: [[STACK_C:%[0-9]+]] = alloc_stack $Optional // CHECK-DAG: store [[ARG]] to [[STACK_C]] diff --git a/test/TBD/specialization.swift b/test/TBD/specialization.swift index 6d00daf8a67c9..1a83c63afea8b 100644 --- a/test/TBD/specialization.swift +++ b/test/TBD/specialization.swift @@ -40,7 +40,7 @@ public func f() { // Generic specialization, from the foo call in f // CHECK-LABEL: // specialized Foo.foo(_:) -// CHECK-NEXT: sil private [noinline] @$s14specialization3FooC3foo33_A6E3E43DB6679655BDF5A878ABC489A0LLyyxmlFSi_Tgm5Tf4d_n : $@convention(thin) () -> () +// CHECK-NEXT: sil private [noinline] @$s14specialization3FooC3foo33_A6E3E43DB6679655BDF5A878ABC489A0LLyyxmlFSi_Tg5Tf4dd_n : $@convention(thin) () -> () // Function signature specialization, from the bar call in Bar.init // CHECK-LABEL: // specialized Bar.bar()