/// 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; }
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); }
/// 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; }