Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-dllimport=defaultLibsOnly: Avoid -linkonce-templates requirement #3816

Merged
merged 1 commit into from
Sep 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions driver/cl_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ cl::opt<DLLImport, true> dllimport(
"None (default with -link-defaultlib-shared=false)"),
clEnumValN(DLLImport::defaultLibsOnly, "defaultLibsOnly",
"Only druntime/Phobos symbols (default with "
"-link-defaultlib-shared and -fvisibility=hidden). May "
"likely need to be coupled with -linkonce-templates to "
"overcome linker errors wrt. instantiated symbols."),
"-link-defaultlib-shared and -fvisibility=hidden)."),
clEnumValN(DLLImport::all, "all",
"All (default with -link-defaultlib-shared and "
"-fvisibility=public)")));
Expand Down
2 changes: 1 addition & 1 deletion gen/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ void DtoDeclareFunction(FuncDeclaration *fdecl, const bool willDefine) {
bool defineAsAvailableExternally = false;
if (willDefine) {
// will be defined anyway after declaration
} else if (defineOnDeclare(fdecl)) {
} else if (defineOnDeclare(fdecl, /*isFunction=*/true)) {
Logger::println("Function is inside a linkonce_odr template, will be "
"defined after declaration.");
if (fdecl->semanticRun < PASSsemantic3done) {
Expand Down
32 changes: 17 additions & 15 deletions gen/llvmhelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,14 +794,6 @@ DValue *DtoPaintType(const Loc &loc, DValue *val, Type *to) {
return new DImValue(to, DtoRVal(val));
}

/******************************************************************************
* TEMPLATE HELPERS
******************************************************************************/

bool defineOnDeclare(Dsymbol* s) {
return global.params.linkonceTemplates && s->isInstantiated();
}

/******************************************************************************
* PROCESSING QUEUE HELPERS
******************************************************************************/
Expand Down Expand Up @@ -1680,12 +1672,8 @@ std::string llvmTypeToString(llvm::Type *type) {
}

// Is the specified symbol defined in the druntime/Phobos libs?
// Note: fuzzy semantics for instantiated symbols, except with
// -linkonce-templates.
// For instantiated symbols: is the template declared in druntime/Phobos?
static bool isDefaultLibSymbol(Dsymbol *sym) {
if (defineOnDeclare(sym))
return false;

auto mod = sym->getModule();
if (!mod)
return false;
Expand All @@ -1705,10 +1693,24 @@ static bool isDefaultLibSymbol(Dsymbol *sym) {
(md->packages.length > 1 && md->packages.ptr[1] == Id::io)));
}

bool dllimportSymbol(Dsymbol *sym) {
bool defineOnDeclare(Dsymbol* sym, bool isFunction) {
if (global.params.linkonceTemplates)
return sym->isInstantiated();

// With -dllimport=defaultLibsOnly, an instantiated data symbol from a
// druntime/Phobos template may be assigned to an arbitrary binary (and culled
// from others via `needsCodegen()`). Define it in each referencing CU and
// never dllimport.
return !isFunction && global.params.dllimport == DLLImport::defaultLibsOnly &&
sym->isInstantiated() && isDefaultLibSymbol(sym);
}

bool dllimportDataSymbol(Dsymbol *sym) {
return sym->isExport() || global.params.dllimport == DLLImport::all ||
(global.params.dllimport == DLLImport::defaultLibsOnly &&
isDefaultLibSymbol(sym));
// exclude instantiated symbols from druntime/Phobos templates (see
// `defineOnDeclare()`)
!sym->isInstantiated() && isDefaultLibSymbol(sym));
}

llvm::GlobalVariable *declareGlobal(const Loc &loc, llvm::Module &module,
Expand Down
13 changes: 7 additions & 6 deletions gen/llvmhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,6 @@ DValue *DtoCast(const Loc &loc, DValue *val, Type *to);
// otherwise returns a new DValue
DValue *DtoPaintType(const Loc &loc, DValue *val, Type *to);

/// Returns true if the specified symbol is to be defined on declaration, for
/// -linkonce-templates.
bool defineOnDeclare(Dsymbol *s);

/// Makes sure the declarations corresponding to the given D symbol have been
/// emitted to the currently processed LLVM module.
///
Expand Down Expand Up @@ -245,8 +241,13 @@ LLConstant *toConstantArray(LLType *ct, LLArrayType *at, T *str, size_t len,

llvm::Constant *buildStringLiteralConstant(StringExp *se, bool zeroTerm);

/// Indicates whether the specified symbol is a general dllimport candidate.
bool dllimportSymbol(Dsymbol *sym);
/// Returns true if the specified symbol is to be defined on declaration,
/// primarily for -linkonce-templates.
bool defineOnDeclare(Dsymbol *sym, bool isFunction);

/// Indicates whether the specified data symbol is a general dllimport
/// candidate.
bool dllimportDataSymbol(Dsymbol *sym);

/// Tries to declare an LLVM global. If a variable with the same mangled name
/// already exists, checks if the types match and returns it instead.
Expand Down
4 changes: 2 additions & 2 deletions ir/iraggr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ bool IrAggr::useDLLImport() const {
if (!global.params.targetTriple->isOSWindows())
return false;

if (dllimportSymbol(aggrdecl)) {
if (dllimportDataSymbol(aggrdecl)) {
// dllimport, unless defined in a root module (=> no extra indirection for
// other root modules, assuming *all* root modules will be linked together
// to one or more binaries).
Expand Down Expand Up @@ -103,7 +103,7 @@ LLConstant *IrAggr::getInitSymbol(bool define) {
init = initGlobal;

if (!define)
define = defineOnDeclare(aggrdecl);
define = defineOnDeclare(aggrdecl, /*isFunction=*/false);
}

if (define) {
Expand Down
6 changes: 3 additions & 3 deletions ir/irclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ LLGlobalVariable *IrClass::getVtblSymbol(bool define) {
/*isConstant=*/true, false, useDLLImport());

if (!define)
define = defineOnDeclare(aggrdecl);
define = defineOnDeclare(aggrdecl, /*isFunction=*/false);
}

if (define) {
Expand Down Expand Up @@ -130,7 +130,7 @@ LLGlobalVariable *IrClass::getClassInfoSymbol(bool define) {
}

if (!define)
define = defineOnDeclare(aggrdecl);
define = defineOnDeclare(aggrdecl, /*isFunction=*/false);
}

if (define) {
Expand Down Expand Up @@ -473,7 +473,7 @@ llvm::GlobalVariable *IrClass::getInterfaceVtblSymbol(BaseClass *b,
interfaceVtblMap.insert({{b->sym, interfaces_index}, gvar});

if (!define)
define = defineOnDeclare(aggrdecl);
define = defineOnDeclare(aggrdecl, /*isFunction=*/false);
}

if (define && !gvar->hasInitializer()) {
Expand Down
2 changes: 1 addition & 1 deletion ir/irmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ llvm::GlobalVariable *IrModule::moduleInfoSymbol() {

const auto irMangle = getIRMangledModuleInfoSymbolName(M);

const bool useDLLImport = !M->isRoot() && dllimportSymbol(M);
const bool useDLLImport = !M->isRoot() && dllimportDataSymbol(M);

moduleInfoVar = declareGlobal(Loc(), gIR->module,
llvm::StructType::create(gIR->context()),
Expand Down
2 changes: 1 addition & 1 deletion ir/irstruct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ LLGlobalVariable* IrStruct::getTypeInfoSymbol(bool define) {
emitTypeInfoMetadata(typeInfo, aggrdecl->type);

if (!define)
define = defineOnDeclare(aggrdecl);
define = defineOnDeclare(aggrdecl, /*isFunction=*/false);
}

if (define) {
Expand Down
4 changes: 2 additions & 2 deletions ir/irvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ LLValue *IrGlobal::getValue(bool define) {
declare();

if (!define)
define = defineOnDeclare(V);
define = defineOnDeclare(V, /*isFunction=*/false);
}

if (define) {
Expand Down Expand Up @@ -86,7 +86,7 @@ void IrGlobal::declare() {
// dllimport isn't supported for thread-local globals (MSVC++ neither)
if (!V->isThreadlocal()) {
// implicitly include extern(D) globals with -dllimport
if (V->isExport() || (V->linkage == LINK::d && dllimportSymbol(V))) {
if (V->isExport() || (V->linkage == LINK::d && dllimportDataSymbol(V))) {
const bool isDefinedInRootModule =
!(V->storage_class & STCextern) && !V->inNonRoot();
if (!isDefinedInRootModule)
Expand Down