mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Whenever we have a reference to a foreign function/variable in SIL, use a mangled name at the SIL level with the C name in the asmname attribute. The expands the use of asmname to three kinds of cases that it hadn't been used in yet: * Declarations imported from C headers/modules * @_cdecl @implementation of C headers/modules * @_cdecl functions in general Some code within the SIL pipeline makes assumptions that the C names of various runtime functions are reflected at the SIL level. For example, the linking of Embedded Swift runtime functions is done by-name, and some of those names refer to C functions (like `swift_retain`) and others refer to Swift functions that use `@_silgen_name` (like `swift_getDefaultExecutor`). Extend the serialized module format to include a table that maps from the asmname of functions/variables over to their mangled names, so we can look up functions by asmname if we want. These tables could also be used for checking for declarations that conflict on their asmname in the future. Right now, we leave it up to LLVM or the linker to do the checking. `@_silgen_name` is not affected by these changes, nor should it be: that hidden feature is specifically meant to affect the name at the SIL level. The vast majority of test changes are SIL tests where we had expected to see the C/C++/Objective-C names in the tests for references to foreign entities, and now we see Swift mangled names (ending in To). The SIL declarations themselves will have a corresponding asmname. Notably, the IRGen tests have *not* changed, because we generally the same IR as before. It's only the modeling at the SIL lever that has changed. Another part of rdar://137014448.
283 lines
8.8 KiB
C++
283 lines
8.8 KiB
C++
//===--- SerializedSILLoader.cpp - A loader for SIL sections --------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define DEBUG_TYPE "serialized-sil-loader"
|
|
|
|
#include "DeserializeSIL.h"
|
|
#include "ModuleFile.h"
|
|
|
|
#include "swift/AST/ASTMangler.h"
|
|
#include "swift/SIL/SILModule.h"
|
|
#include "swift/SIL/SILMoveOnlyDeinit.h"
|
|
#include "swift/Serialization/SerializedModuleLoader.h"
|
|
#include "swift/Serialization/SerializedSILLoader.h"
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
using namespace swift;
|
|
|
|
SerializedSILLoader::SerializedSILLoader(
|
|
ASTContext &Ctx, SILModule *SILMod,
|
|
DeserializationNotificationHandlerSet *callbacks) : Context(Ctx) {
|
|
|
|
// Get a list of SerializedModules from ASTContext.
|
|
// FIXME: Iterating over LoadedModules is not a good way to do this.
|
|
for (const auto &Entry : Ctx.getLoadedModules()) {
|
|
for (auto File : Entry.second->getFiles()) {
|
|
if (auto LoadedAST = dyn_cast<SerializedASTFile>(File)) {
|
|
auto Des = new SILDeserializer(&LoadedAST->File, *SILMod, callbacks);
|
|
LoadedSILSections.emplace_back(Des);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SerializedSILLoader::~SerializedSILLoader() {}
|
|
|
|
SILFunction *SerializedSILLoader::lookupSILFunction(SILFunction *Callee,
|
|
bool onlyUpdateLinkage) {
|
|
// It is possible that one module has a declaration of a SILFunction, while
|
|
// another has the full definition.
|
|
SILFunction *retVal = nullptr;
|
|
for (auto &Des : LoadedSILSections) {
|
|
if (auto Func = Des->lookupSILFunction(Callee,
|
|
/*declarationOnly*/ onlyUpdateLinkage)) {
|
|
LLVM_DEBUG(llvm::dbgs() << "Deserialized " << Func->getName() << " from "
|
|
<< Des->getModuleIdentifier().str() << "\n");
|
|
if (!Func->empty())
|
|
return Func;
|
|
retVal = Func;
|
|
}
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
SILFunction *
|
|
SerializedSILLoader::lookupSILFunction(StringRef Name,
|
|
std::optional<SILLinkage> Linkage,
|
|
bool byAsmName) {
|
|
for (auto &Des : LoadedSILSections) {
|
|
if (auto *Func = Des->lookupSILFunction(Name, /*declarationOnly*/ true,
|
|
byAsmName)) {
|
|
LLVM_DEBUG(llvm::dbgs() << "Deserialized " << Func->getName() << " from "
|
|
<< Des->getModuleIdentifier().str() << "\n");
|
|
if (Linkage) {
|
|
// This is not the linkage we are looking for.
|
|
if (Func->getLinkage() != *Linkage) {
|
|
LLVM_DEBUG(llvm::dbgs()
|
|
<< "Wrong linkage for Function: "
|
|
<< Func->getName() << " : "
|
|
<< (int)Func->getLinkage() << "\n");
|
|
Des->invalidateFunction(Func);
|
|
Func->getModule().eraseFunction(Func);
|
|
continue;
|
|
}
|
|
}
|
|
return Func;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
SILGlobalVariable *
|
|
SerializedSILLoader::lookupSILGlobalVariable(StringRef Name, bool byAsmName) {
|
|
for (auto &Des : LoadedSILSections) {
|
|
if (auto *G = Des->lookupSILGlobalVariable(Name, byAsmName)) {
|
|
return G;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool SerializedSILLoader::hasSILFunction(StringRef Name,
|
|
std::optional<SILLinkage> Linkage) {
|
|
// It is possible that one module has a declaration of a SILFunction, while
|
|
// another has the full definition.
|
|
SILFunction *retVal = nullptr;
|
|
for (auto &Des : LoadedSILSections) {
|
|
if (Des->hasSILFunction(Name, Linkage))
|
|
return true;
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
SILVTable *SerializedSILLoader::lookupVTable(const ClassDecl *C) {
|
|
Mangle::ASTMangler mangler(C->getASTContext());
|
|
std::string mangledClassName = mangler.mangleNominalType(C);
|
|
|
|
for (auto &Des : LoadedSILSections) {
|
|
if (auto VT = Des->lookupVTable(mangledClassName))
|
|
return VT;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
SILMoveOnlyDeinit *
|
|
SerializedSILLoader::lookupMoveOnlyDeinit(const NominalTypeDecl *nomDecl) {
|
|
Mangle::ASTMangler mangler(nomDecl->getASTContext());
|
|
std::string mangledClassName = mangler.mangleNominalType(nomDecl);
|
|
|
|
for (auto &des : LoadedSILSections) {
|
|
if (auto *tbl = des->lookupMoveOnlyDeinit(mangledClassName))
|
|
return tbl;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
SILWitnessTable *SerializedSILLoader::lookupWitnessTable(SILWitnessTable *WT) {
|
|
for (auto &Des : LoadedSILSections)
|
|
if (auto wT = Des->lookupWitnessTable(WT))
|
|
return wT;
|
|
return nullptr;
|
|
}
|
|
|
|
SILDefaultWitnessTable *SerializedSILLoader::
|
|
lookupDefaultWitnessTable(SILDefaultWitnessTable *WT) {
|
|
for (auto &Des : LoadedSILSections)
|
|
if (auto wT = Des->lookupDefaultWitnessTable(WT))
|
|
return wT;
|
|
return nullptr;
|
|
}
|
|
|
|
SILDefaultOverrideTable *
|
|
SerializedSILLoader::lookupDefaultOverrideTable(SILDefaultOverrideTable *OT) {
|
|
for (auto &Des : LoadedSILSections)
|
|
if (auto oT = Des->lookupDefaultOverrideTable(OT))
|
|
return oT;
|
|
return nullptr;
|
|
}
|
|
|
|
SILDifferentiabilityWitness *
|
|
SerializedSILLoader::lookupDifferentiabilityWitness(
|
|
SILDifferentiabilityWitnessKey key) {
|
|
Mangle::ASTMangler mangler(Context);
|
|
auto mangledKey = mangler.mangleSILDifferentiabilityWitness(
|
|
key.originalFunctionName, key.kind, key.config);
|
|
// It is possible that one module has a declaration of a
|
|
// SILDifferentiabilityWitness, while another has the full definition.
|
|
SILDifferentiabilityWitness *dw = nullptr;
|
|
for (auto &Des : LoadedSILSections) {
|
|
dw = Des->lookupDifferentiabilityWitness(mangledKey);
|
|
if (dw && dw->isDefinition())
|
|
return dw;
|
|
}
|
|
return dw;
|
|
}
|
|
|
|
void SerializedSILLoader::invalidateAllCaches() {
|
|
for (auto &des : LoadedSILSections)
|
|
des->invalidateAllCaches();
|
|
}
|
|
|
|
bool SerializedSILLoader::invalidateFunction(SILFunction *fn) {
|
|
for (auto &des : LoadedSILSections)
|
|
if (des->invalidateFunction(fn))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool SerializedSILLoader::invalidateGlobalVariable(SILGlobalVariable *gv) {
|
|
for (auto &des : LoadedSILSections)
|
|
if (des->invalidateGlobalVariable(gv))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool SerializedSILLoader::invalidateVTable(SILVTable *vt) {
|
|
for (auto &des : LoadedSILSections)
|
|
if (des->invalidateVTable(vt))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool SerializedSILLoader::invalidateWitnessTable(SILWitnessTable *wt) {
|
|
for (auto &des : LoadedSILSections)
|
|
if (des->invalidateWitnessTable(wt))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool SerializedSILLoader::invalidateDefaultWitnessTable(
|
|
SILDefaultWitnessTable *wt) {
|
|
for (auto &des : LoadedSILSections)
|
|
if (des->invalidateDefaultWitnessTable(wt))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool SerializedSILLoader::invalidateProperty(SILProperty *p) {
|
|
for (auto &des : LoadedSILSections)
|
|
if (des->invalidateProperty(p))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool SerializedSILLoader::invalidateDifferentiabilityWitness(
|
|
SILDifferentiabilityWitness *w) {
|
|
for (auto &des : LoadedSILSections)
|
|
if (des->invalidateDifferentiabilityWitness(w))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
// FIXME: Not the best interface. We know exactly which FileUnits may have SIL
|
|
// those in the main module.
|
|
void SerializedSILLoader::getAllForModule(Identifier Mod,
|
|
FileUnit *PrimaryFile) {
|
|
for (auto &Des : LoadedSILSections) {
|
|
if (Des->getModuleIdentifier() == Mod) {
|
|
Des->getAll(PrimaryFile ?
|
|
Des->getFile() != PrimaryFile : false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SerializedSILLoader::getAllSILFunctions() {
|
|
for (auto &Des : LoadedSILSections)
|
|
Des->getAllSILFunctions();
|
|
}
|
|
|
|
/// Deserialize all VTables in all SILModules.
|
|
void SerializedSILLoader::getAllVTables() {
|
|
for (auto &Des : LoadedSILSections)
|
|
Des->getAllVTables();
|
|
}
|
|
|
|
/// Deserialize all WitnessTables in all SILModules.
|
|
void SerializedSILLoader::getAllWitnessTables() {
|
|
for (auto &Des : LoadedSILSections)
|
|
Des->getAllWitnessTables();
|
|
}
|
|
|
|
/// Deserialize all DefaultWitnessTables in all SILModules.
|
|
void SerializedSILLoader::getAllDefaultWitnessTables() {
|
|
for (auto &Des : LoadedSILSections)
|
|
Des->getAllDefaultWitnessTables();
|
|
}
|
|
|
|
/// Deserialize all DefaultOverrideTables in all SILModules.
|
|
void SerializedSILLoader::getAllDefaultOverrideTables() {
|
|
for (auto &Des : LoadedSILSections)
|
|
Des->getAllDefaultOverrideTables();
|
|
}
|
|
|
|
/// Deserialize all Properties in all SILModules.
|
|
void SerializedSILLoader::getAllProperties() {
|
|
for (auto &Des : LoadedSILSections)
|
|
Des->getAllProperties();
|
|
}
|
|
|
|
/// Deserialize all DifferentiabilityWitnesses in all SILModules.
|
|
void SerializedSILLoader::getAllDifferentiabilityWitnesses() {
|
|
for (auto &Des : LoadedSILSections)
|
|
Des->getAllDifferentiabilityWitnesses();
|
|
}
|