std::string FunctionSignatureInfo::getOptimizedName() const { Mangle::Mangler M; auto P = SpecializationPass::FunctionSignatureOpts; FunctionSignatureSpecializationMangler FSSM(P, M, F); // Handle arguments' changes. for (unsigned i : indices(ArgDescList)) { const ArgumentDescriptor &Arg = ArgDescList[i]; if (Arg.IsEntirelyDead) { FSSM.setArgumentDead(i); } // If we have an @owned argument and found a callee release for it, // convert the argument to guaranteed. if (!Arg.CalleeRelease.empty()) { FSSM.setArgumentOwnedToGuaranteed(i); } // If this argument is not dead and we can explode it, add 's' to the // mangling. if (Arg.Explode && !Arg.IsEntirelyDead) { FSSM.setArgumentSROA(i); } } // Handle return value's change. // FIXME: handle multiple direct results here if (ResultDescList.size() == 1 && !ResultDescList[0].CalleeRetain.empty()) FSSM.setReturnValueOwnedToUnowned(); FSSM.mangle(); return M.finalize(); }
/// Create a getter function from the initializer function. static SILFunction *genGetterFromInit(SILFunction *InitF, VarDecl *varDecl) { // Generate a getter from the global init function without side-effects. Mangle::Mangler getterMangler; getterMangler.mangleGlobalGetterEntity(varDecl); auto getterName = getterMangler.finalize(); // Check if a getter was generated already. if (auto *F = InitF->getModule().lookUpFunction(getterName)) return F; auto refType = varDecl->getType().getCanonicalTypeOrNull(); // Function takes no arguments and returns refType SILResultInfo ResultInfo(refType, ResultConvention::Owned); SILFunctionType::ExtInfo EInfo; EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin); auto LoweredType = SILFunctionType::get(nullptr, EInfo, ParameterConvention::Direct_Owned, { }, ResultInfo, None, InitF->getASTContext()); auto *GetterF = InitF->getModule().getOrCreateFunction(InitF->getLocation(), getterName, SILLinkage::PrivateExternal, LoweredType, IsBare_t::IsBare, IsTransparent_t::IsNotTransparent, IsFragile_t::IsFragile); auto *EntryBB = GetterF->createBasicBlock(); // Copy InitF into GetterF BasicBlockCloner Cloner(&*InitF->begin(), EntryBB, /*WithinFunction=*/false); Cloner.clone(); GetterF->setInlined(); // Find the store instruction auto BB = EntryBB; SILValue Val; SILInstruction *Store; for (auto II = BB->begin(), E = BB->end(); II != E;) { auto &I = *II++; if (isa<AllocGlobalInst>(&I)) { I.eraseFromParent(); continue; } if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { Val = SI->getSrc(); Store = SI; continue; } if (ReturnInst *RI = dyn_cast<ReturnInst>(&I)) { SILBuilderWithScope B(RI); B.createReturn(RI->getLoc(), Val); eraseUsesOfInstruction(RI); recursivelyDeleteTriviallyDeadInstructions(RI, true); recursivelyDeleteTriviallyDeadInstructions(Store, true); return GetterF; } } InitF->getModule().getFunctionList().addNodeToList(GetterF); return GetterF; }
std::string FunctionAnalyzer::getOptimizedName() { Mangle::Mangler M; auto P = SpecializationPass::FunctionSignatureOpts; FunctionSignatureSpecializationMangler FSSM(P, M, F); for (unsigned i : indices(ArgDescList)) { const ArgumentDescriptor &Arg = ArgDescList[i]; if (Arg.IsDead) { FSSM.setArgumentDead(i); } // If we have an @owned argument and found a callee release for it, // convert the argument to guaranteed. if (Arg.CalleeRelease) { FSSM.setArgumentOwnedToGuaranteed(i); } // If this argument is not dead and we can explode it, add 's' to the // mangling. if (Arg.shouldExplode() && !Arg.IsDead) { FSSM.setArgumentSROA(i); } } FSSM.mangle(); return M.finalize(); }
void addDecl(const NominalTypeDecl *decl) { auto type = decl->getDeclaredInterfaceType()->getCanonicalType(); Mangle::Mangler mangler; mangler.setModuleContext(decl->getModuleContext()); mangler.mangleType(type, 0); auto mangledName = IGM.getAddrOfStringForTypeRef(mangler.finalize()); addRelativeAddress(mangledName); switch (decl->getKind()) { case DeclKind::Class: case DeclKind::Struct: { auto properties = decl->getStoredProperties(); addConstantInt32(std::distance(properties.begin(), properties.end())); addConstantInt32(fieldRecordSize); for (auto property : properties) addFieldDecl(property); break; } case DeclKind::Enum: { auto enumDecl = cast<EnumDecl>(decl); auto cases = enumDecl->getAllElements(); addConstantInt32(std::distance(cases.begin(), cases.end())); addConstantInt32(fieldRecordSize); for (auto enumCase : cases) addFieldDecl(enumCase); break; } default: llvm_unreachable("Not a nominal type"); break; } }
static std::string getClonedName(SILFunction *F, ParamIndexList &PromotedParamIndices) { Mangle::Mangler M; auto P = SpecializationPass::AllocBoxToStack; FunctionSignatureSpecializationMangler FSSM(P, M, F); for (unsigned i : PromotedParamIndices) FSSM.setArgumentBoxToStack(i); FSSM.mangle(); return M.finalize(); }
static std::string mangleGetter(VarDecl *varDecl) { Mangle::Mangler getterMangler; getterMangler.append("_T"); getterMangler.mangleGlobalGetterEntity(varDecl); std::string Old = getterMangler.finalize(); NewMangling::ASTMangler NewMangler; std::string New = NewMangler.mangleGlobalGetterEntity(varDecl); return NewMangling::selectMangling(Old, New); }
void addFieldDecl(const ValueDecl *value) { auto type = value->getInterfaceType()->getCanonicalType(); Mangle::Mangler mangler; mangler.setModuleContext(value->getModuleContext()); mangler.mangleType(type, 0); auto mangledName = IGM.getAddrOfStringForTypeRef(mangler.finalize()); addRelativeAddress(mangledName); if (IGM.Opts.StripReflectionNames) { addConstantInt32(0); } else { auto fieldName = IGM.getAddrOfFieldName(value->getNameStr()); addRelativeAddress(fieldName); } }
std::string CallSiteDescriptor::createName() const { Mangle::Mangler M; auto P = SpecializationPass::ClosureSpecializer; FunctionSignatureSpecializationMangler FSSM(P, M, getApplyCallee()); if (auto *PAI = dyn_cast<PartialApplyInst>(getClosure())) { FSSM.setArgumentClosureProp(getClosureIndex(), PAI); FSSM.mangle(); return M.finalize(); } auto *TTTFI = cast<ThinToThickFunctionInst>(getClosure()); FSSM.setArgumentClosureProp(getClosureIndex(), TTTFI); FSSM.mangle(); return M.finalize(); }
std::string CallSiteDescriptor::createName() const { Mangle::Mangler M; auto P = Demangle::SpecializationPass::ClosureSpecializer; FunctionSignatureSpecializationMangler OldFSSM(P, M, isFragile(), getApplyCallee()); NewMangling::FunctionSignatureSpecializationMangler NewFSSM(P, isFragile(), getApplyCallee()); if (auto *PAI = dyn_cast<PartialApplyInst>(getClosure())) { OldFSSM.setArgumentClosureProp(getClosureIndex(), PAI); NewFSSM.setArgumentClosureProp(getClosureIndex(), PAI); } else { auto *TTTFI = cast<ThinToThickFunctionInst>(getClosure()); OldFSSM.setArgumentClosureProp(getClosureIndex(), TTTFI); NewFSSM.setArgumentClosureProp(getClosureIndex(), TTTFI); } OldFSSM.mangle(); std::string Old = M.finalize(); std::string New = NewFSSM.mangle(); return NewMangling::selectMangling(Old, New); }
GenericFuncSpecializer::GenericFuncSpecializer(SILFunction *GenericFunc, ArrayRef<Substitution> ParamSubs, IsFragile_t Fragile, const ReabstractionInfo &ReInfo) : M(GenericFunc->getModule()), GenericFunc(GenericFunc), ParamSubs(ParamSubs), Fragile(Fragile), ReInfo(ReInfo) { assert(GenericFunc->isDefinition() && "Expected definition to specialize!"); if (GenericFunc->getContextGenericParams()) ContextSubs = GenericFunc->getContextGenericParams() ->getSubstitutionMap(ParamSubs); Mangle::Mangler Mangler; GenericSpecializationMangler GenericMangler(Mangler, GenericFunc, ParamSubs, Fragile); GenericMangler.mangle(); ClonedName = Mangler.finalize(); DEBUG(llvm::dbgs() << " Specialized function " << ClonedName << '\n'); }
/// Generate getter from the initialization code whose /// result is stored by a given store instruction. static SILFunction *genGetterFromInit(StoreInst *Store, SILGlobalVariable *SILG) { auto *varDecl = SILG->getDecl(); Mangle::Mangler getterMangler; getterMangler.mangleGlobalGetterEntity(varDecl); auto getterName = getterMangler.finalize(); // Check if a getter was generated already. if (auto *F = Store->getModule().lookUpFunction(getterName)) return F; // Find the code that performs the initialization first. // Recursively walk the SIL value being assigned to the SILG. auto V = Store->getSrc(); SmallVector<SILInstruction *, 8> ReverseInsns; SmallVector<SILInstruction *, 8> Insns; ReverseInsns.push_back(Store); ReverseInsns.push_back(dyn_cast<SILInstruction>(Store->getDest())); if (!analyzeStaticInitializer(V, ReverseInsns)) return nullptr; // Produce a correct order of instructions. while (!ReverseInsns.empty()) { Insns.push_back(ReverseInsns.pop_back_val()); } // Generate a getter from the global init function without side-effects. auto refType = varDecl->getType().getCanonicalTypeOrNull(); // Function takes no arguments and returns refType SILResultInfo ResultInfo(refType, ResultConvention::Owned); SILFunctionType::ExtInfo EInfo; EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin); auto LoweredType = SILFunctionType::get(nullptr, EInfo, ParameterConvention::Direct_Owned, { }, ResultInfo, None, Store->getModule().getASTContext()); auto *GetterF = Store->getModule().getOrCreateFunction(Store->getLoc(), getterName, SILLinkage::PrivateExternal, LoweredType, IsBare_t::IsBare, IsTransparent_t::IsNotTransparent, IsFragile_t::IsFragile); GetterF->setDebugScope(Store->getFunction()->getDebugScope()); auto *EntryBB = GetterF->createBasicBlock(); // Copy instructions into GetterF InstructionsCloner Cloner(*GetterF, Insns, EntryBB); Cloner.clone(); GetterF->setInlined(); // Find the store instruction auto BB = EntryBB; SILValue Val; for (auto &I : *BB) { if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { Val = SI->getSrc(); SILBuilderWithScope B(SI); B.createReturn(SI->getLoc(), Val); eraseUsesOfInstruction(SI); recursivelyDeleteTriviallyDeadInstructions(SI, true); return GetterF; } } Store->getModule().getFunctionList().addNodeToList(GetterF); return GetterF; }
SILFunction *MaterializeForSetEmitter::createCallback(SILFunction &F, GeneratorFn generator) { auto &ctx = SGM.getASTContext(); // Mangle this as if it were a conformance thunk for a closure // within the witness. std::string name; { ClosureExpr closure(/*patterns*/ nullptr, /*throws*/ SourceLoc(), /*arrow*/ SourceLoc(), /*in*/ SourceLoc(), /*result*/ TypeLoc(), /*discriminator*/ 0, /*context*/ Witness); closure.setType(getMaterializeForSetCallbackType(ctx, getSelfTypeForCallbackDeclaration(Witness))); closure.getCaptureInfo().setGenericParamCaptures(true); Mangle::Mangler mangler; if (Conformance) { mangler.append("_TTW"); mangler.mangleProtocolConformance(Conformance); } else { mangler.append("_T"); } mangler.mangleClosureEntity(&closure, /*uncurryLevel=*/1); name = mangler.finalize(); } // Get lowered formal types for callback parameters. Type selfType = SelfInterfaceType; Type selfMetatypeType = MetatypeType::get(SelfInterfaceType, MetatypeRepresentation::Thick); { GenericContextScope scope(SGM.Types, GenericSig); // If 'self' is a metatype, make it @thin or @thick as needed, but not inside // selfMetatypeType. if (auto metatype = selfType->getAs<MetatypeType>()) { if (!metatype->hasRepresentation()) selfType = SGM.getLoweredType(metatype).getSwiftRValueType(); } } // Create the SILFunctionType for the callback. SILParameterInfo params[] = { { ctx.TheRawPointerType, ParameterConvention::Direct_Unowned }, { ctx.TheUnsafeValueBufferType, ParameterConvention::Indirect_Inout }, { selfType->getCanonicalType(), ParameterConvention::Indirect_Inout }, { selfMetatypeType->getCanonicalType(), ParameterConvention::Direct_Unowned }, }; SILResultInfo result = { TupleType::getEmpty(ctx), ResultConvention::Unowned }; auto extInfo = SILFunctionType::ExtInfo() .withRepresentation(SILFunctionTypeRepresentation::Thin); auto callbackType = SILFunctionType::get(GenericSig, extInfo, /*callee*/ ParameterConvention::Direct_Unowned, params, result, None, ctx); auto callback = SGM.M.getOrCreateFunction(Witness, name, Linkage, callbackType, IsBare, F.isTransparent(), F.isFragile()); callback->setContextGenericParams(GenericParams); callback->setDebugScope(new (SGM.M) SILDebugScope(Witness, *callback)); PrettyStackTraceSILFunction X("silgen materializeForSet callback", callback); { SILGenFunction gen(SGM, *callback); auto makeParam = [&](unsigned index) -> SILArgument* { SILType type = gen.F.mapTypeIntoContext(params[index].getSILType()); return new (SGM.M) SILArgument(gen.F.begin(), type); }; // Add arguments for all the parameters. auto valueBuffer = makeParam(0); auto storageBuffer = makeParam(1); auto self = makeParam(2); (void) makeParam(3); SILLocation loc = Witness; loc.markAutoGenerated(); // Call the generator function we were provided. { LexicalScope scope(gen.Cleanups, gen, CleanupLocation::get(loc)); generator(gen, loc, valueBuffer, storageBuffer, self); } // Return void. auto result = gen.emitEmptyTuple(loc); gen.B.createReturn(loc, result); } callback->verify(); return callback; }