SILType SILType::substGenericArgs(SILModule &M, ArrayRef<Substitution> Subs) const { SILFunctionType *fnTy = getSwiftRValueType()->castTo<SILFunctionType>(); if (Subs.empty()) { assert(!fnTy->isPolymorphic() && "function type without subs must not " "be polymorphic."); return *this; } assert(fnTy->isPolymorphic() && "Can only subst interface generic args on " "polymorphic function types."); CanSILFunctionType canFnTy = fnTy->substGenericArgs(M, Subs); return SILType::getPrimitiveObjectType(canFnTy); }
/// \brief Create the function corresponding to the clone of the /// original closure with the signature modified to reflect promoted /// parameters (which are specified by PromotedArgIndices). SILFunction *PromotedParamCloner::initCloned(SILFunction *Orig, IsSerialized_t Serialized, ArgIndexList &PromotedArgIndices, llvm::StringRef ClonedName) { SILModule &M = Orig->getModule(); SmallVector<SILParameterInfo, 4> ClonedInterfaceArgTys; // Generate a new parameter list with deleted parameters removed. SILFunctionType *OrigFTI = Orig->getLoweredFunctionType(); unsigned Index = Orig->getConventions().getSILArgIndexOfFirstParam(); for (auto ¶m : OrigFTI->getParameters()) { if (count(PromotedArgIndices, Index)) { auto boxTy = param.getSILStorageType().castTo<SILBoxType>(); assert(boxTy->getLayout()->getFields().size() == 1 && "promoting compound box not implemented"); SILType paramTy; { Lowering::GenericContextScope scope(Orig->getModule().Types, OrigFTI->getGenericSignature()); paramTy = boxTy->getFieldType(Orig->getModule(), 0); } auto promotedParam = SILParameterInfo(paramTy.getSwiftRValueType(), ParameterConvention::Indirect_InoutAliasable); ClonedInterfaceArgTys.push_back(promotedParam); } else { ClonedInterfaceArgTys.push_back(param); } ++Index; } // Create the new function type for the cloned function with some of // the parameters promoted. auto ClonedTy = SILFunctionType::get( OrigFTI->getGenericSignature(), OrigFTI->getExtInfo(), OrigFTI->getCalleeConvention(), ClonedInterfaceArgTys, OrigFTI->getResults(), OrigFTI->getOptionalErrorResult(), M.getASTContext()); assert((Orig->isTransparent() || Orig->isBare() || Orig->getLocation()) && "SILFunction missing location"); assert((Orig->isTransparent() || Orig->isBare() || Orig->getDebugScope()) && "SILFunction missing DebugScope"); assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned"); auto *Fn = M.createFunction( SILLinkage::Shared, ClonedName, ClonedTy, Orig->getGenericEnvironment(), Orig->getLocation(), Orig->isBare(), IsNotTransparent, Serialized, Orig->getEntryCount(), Orig->isThunk(), Orig->getClassSubclassScope(), Orig->getInlineStrategy(), Orig->getEffectsKind(), Orig, Orig->getDebugScope()); for (auto &Attr : Orig->getSemanticsAttrs()) { Fn->addSemanticsAttr(Attr); } if (Orig->hasUnqualifiedOwnership()) { Fn->setUnqualifiedOwnership(); } return Fn; }
/// \brief Create the function corresponding to the clone of the /// original closure with the signature modified to reflect promoted /// parameters (which are specified by PromotedParamIndices). SILFunction* PromotedParamCloner::initCloned(SILFunction *Orig, ParamIndexList &PromotedParamIndices, llvm::StringRef ClonedName) { SILModule &M = Orig->getModule(); SmallVector<SILParameterInfo, 4> ClonedInterfaceArgTys; // Generate a new parameter list with deleted parameters removed. SILFunctionType *OrigFTI = Orig->getLoweredFunctionType(); unsigned Index = OrigFTI->getNumIndirectResults(); for (auto ¶m : OrigFTI->getParameters()) { if (std::count(PromotedParamIndices.begin(), PromotedParamIndices.end(), Index)) { auto paramTy = param.getType()->castTo<SILBoxType>() ->getBoxedAddressType(); auto promotedParam = SILParameterInfo(paramTy.getSwiftRValueType(), ParameterConvention::Indirect_InoutAliasable); ClonedInterfaceArgTys.push_back(promotedParam); } else { ClonedInterfaceArgTys.push_back(param); } ++Index; } // Create the new function type for the cloned function with some of // the parameters promoted. auto ClonedTy = SILFunctionType::get(OrigFTI->getGenericSignature(), OrigFTI->getExtInfo(), OrigFTI->getCalleeConvention(), ClonedInterfaceArgTys, OrigFTI->getAllResults(), OrigFTI->getOptionalErrorResult(), M.getASTContext()); assert((Orig->isTransparent() || Orig->isBare() || Orig->getLocation()) && "SILFunction missing location"); assert((Orig->isTransparent() || Orig->isBare() || Orig->getDebugScope()) && "SILFunction missing DebugScope"); assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned"); auto *Fn = M.getOrCreateFunction( SILLinkage::Shared, ClonedName, ClonedTy, Orig->getContextGenericParams(), Orig->getLocation(), Orig->isBare(), IsNotTransparent, Orig->isFragile(), Orig->isThunk(), Orig->getClassVisibility(), Orig->getInlineStrategy(), Orig->getEffectsKind(), Orig, Orig->getDebugScope()); for (auto &Attr : Orig->getSemanticsAttrs()) { Fn->addSemanticsAttr(Attr); } Fn->setDeclCtx(Orig->getDeclContext()); return Fn; }
std::string GenericSpecializationMangler::mangle(GenericSignature *Sig) { beginMangling(); if (!Sig) { SILFunctionType *FTy = Function->getLoweredFunctionType(); Sig = FTy->getGenericSignature(); } bool First = true; Sig->forEachParam([&](GenericTypeParamType *ParamType, bool Canonical) { if (Canonical) { appendType(Type(ParamType).subst(SubMap)->getCanonicalType()); appendListSeparator(First); } }); assert(!First && "no generic substitutions"); if (isInlined) appendSpecializationOperator("Ti"); else appendSpecializationOperator(isReAbstracted ? "Tg" : "TG"); return finalize(); }
bool swift::ArraySemanticsCall::replaceByAppendingValues( SILModule &M, SILFunction *AppendFn, SILFunction *ReserveFn, const SmallVectorImpl<SILValue> &Vals, SubstitutionMap Subs) { assert(getKind() == ArrayCallKind::kAppendContentsOf && "Must be an append_contentsOf call"); assert(AppendFn && "Must provide an append SILFunction"); // We only handle loadable types. if (any_of(Vals, [&M](SILValue V) -> bool { return !V->getType().isLoadable(M); })) return false; CanSILFunctionType AppendFnTy = AppendFn->getLoweredFunctionType(); SILValue ArrRef = SemanticsCall->getArgument(1); SILBuilderWithScope Builder(SemanticsCall); auto Loc = SemanticsCall->getLoc(); auto *FnRef = Builder.createFunctionRefFor(Loc, AppendFn); if (Vals.size() > 1) { // Create a call to reserveCapacityForAppend() to reserve space for multiple // elements. FunctionRefBaseInst *ReserveFnRef = Builder.createFunctionRefFor(Loc, ReserveFn); SILFunctionType *ReserveFnTy = ReserveFnRef->getType().castTo<SILFunctionType>(); assert(ReserveFnTy->getNumParameters() == 2); StructType *IntType = ReserveFnTy->getParameters()[0].getType()->castTo<StructType>(); StructDecl *IntDecl = IntType->getDecl(); VarDecl *field = *IntDecl->getStoredProperties().begin(); SILType BuiltinIntTy =SILType::getPrimitiveObjectType( field->getInterfaceType()->getCanonicalType()); IntegerLiteralInst *CapacityLiteral = Builder.createIntegerLiteral(Loc, BuiltinIntTy, Vals.size()); StructInst *Capacity = Builder.createStruct(Loc, SILType::getPrimitiveObjectType(CanType(IntType)), {CapacityLiteral}); Builder.createApply(Loc, ReserveFnRef, Subs, {Capacity, ArrRef}, false); } for (SILValue V : Vals) { auto SubTy = V->getType(); auto &ValLowering = Builder.getModule().getTypeLowering(SubTy); auto CopiedVal = ValLowering.emitCopyValue(Builder, Loc, V); auto *AllocStackInst = Builder.createAllocStack(Loc, SubTy); ValLowering.emitStoreOfCopy(Builder, Loc, CopiedVal, AllocStackInst, IsInitialization_t::IsInitialization); SILValue Args[] = {AllocStackInst, ArrRef}; Builder.createApply(Loc, FnRef, Subs, Args, false); Builder.createDeallocStack(Loc, AllocStackInst); if (!isConsumedParameter(AppendFnTy->getParameters()[0].getConvention())) { ValLowering.emitDestroyValue(Builder, Loc, CopiedVal); } } CanSILFunctionType AppendContentsOfFnTy = SemanticsCall->getReferencedFunction()->getLoweredFunctionType(); if (AppendContentsOfFnTy->getParameters()[0].getConvention() == ParameterConvention::Direct_Owned) { SILValue SrcArray = SemanticsCall->getArgument(0); Builder.createReleaseValue(SemanticsCall->getLoc(), SrcArray, Builder.getDefaultAtomicity()); } removeCall(); return true; }