mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-03-03 19:13:15 +01:00
Run semantic3 on imported modules, and emit new symbols with
`available_externally` linkage. This allows the inliner to inline functions from other modules while telling the code generator to ignore those functions (treat them as declarations) Still generates a few extra `TypeInfo`s and strings... Disabled when generating debug info because I don't really understand it, and it doesn't like this.
This commit is contained in:
@@ -241,6 +241,13 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
|
||||
// global variable
|
||||
if (VarDeclaration* vd = sym->isVarDeclaration())
|
||||
{
|
||||
if (mustDefineSymbol(vd))
|
||||
Logger::println("Variable %savailable externally: %s", (vd->availableExternally ? "" : "not "), vd->toChars());
|
||||
#if LLVM_REV >= 68940
|
||||
// generated by inlining semantics run
|
||||
if (vd->availableExternally && mustDefineSymbol(sym))
|
||||
return llvm::GlobalValue::AvailableExternallyLinkage;
|
||||
#endif
|
||||
// template
|
||||
if (needsTemplateLinkage(sym))
|
||||
return TEMPLATE_LINKAGE_TYPE;
|
||||
@@ -248,15 +255,22 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
|
||||
// function
|
||||
else if (FuncDeclaration* fdecl = sym->isFuncDeclaration())
|
||||
{
|
||||
if (mustDefineSymbol(fdecl))
|
||||
Logger::println("Function %savailable externally: %s", (fdecl->availableExternally ? "" : "not "), fdecl->toChars());
|
||||
assert(fdecl->type->ty == Tfunction);
|
||||
TypeFunction* ft = (TypeFunction*)fdecl->type;
|
||||
|
||||
// array operations are always template linkage
|
||||
if (fdecl->isArrayOp)
|
||||
return TEMPLATE_LINKAGE_TYPE;
|
||||
// intrinsics are always external
|
||||
if (fdecl->llvmInternal == LLVMintrinsic)
|
||||
return llvm::GlobalValue::ExternalLinkage;
|
||||
#if LLVM_REV >= 68940
|
||||
// generated by inlining semantics run
|
||||
if (fdecl->availableExternally && mustDefineSymbol(sym))
|
||||
return llvm::GlobalValue::AvailableExternallyLinkage;
|
||||
#endif
|
||||
// array operations are always template linkage
|
||||
if (fdecl->isArrayOp)
|
||||
return TEMPLATE_LINKAGE_TYPE;
|
||||
// template instances should have weak linkage
|
||||
// but only if there's a body, and it's not naked
|
||||
// otherwise we make it external
|
||||
@@ -269,6 +283,13 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
|
||||
// class
|
||||
else if (ClassDeclaration* cd = sym->isClassDeclaration())
|
||||
{
|
||||
if (mustDefineSymbol(cd))
|
||||
Logger::println("Class %savailable externally: %s", (cd->availableExternally ? "" : "not "), vd->toChars());
|
||||
#if LLVM_REV >= 68940
|
||||
// generated by inlining semantics run
|
||||
if (cd->availableExternally && mustDefineSymbol(sym))
|
||||
return llvm::GlobalValue::AvailableExternallyLinkage;
|
||||
#endif
|
||||
// template
|
||||
if (needsTemplateLinkage(cd))
|
||||
return TEMPLATE_LINKAGE_TYPE;
|
||||
@@ -278,8 +299,8 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
|
||||
assert(0 && "not global/function");
|
||||
}
|
||||
|
||||
// The following breaks for nested naked functions, so check for that.
|
||||
bool skipNestedCheck = false;
|
||||
// The following breaks for nested naked functions and other declarations, so check for that.
|
||||
bool skipNestedCheck = !mustDefineSymbol(sym);
|
||||
if (FuncDeclaration* fd = sym->isFuncDeclaration())
|
||||
skipNestedCheck = (fd->naked != 0);
|
||||
|
||||
@@ -306,16 +327,36 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
|
||||
return llvm::GlobalValue::ExternalLinkage;
|
||||
}
|
||||
|
||||
static bool isAvailableExternally(Dsymbol* sym)
|
||||
{
|
||||
if (VarDeclaration* vd = sym->isVarDeclaration())
|
||||
return vd->availableExternally;
|
||||
if (FuncDeclaration* fd = sym->isFuncDeclaration())
|
||||
return fd->availableExternally;
|
||||
if (AggregateDeclaration* ad = sym->isAggregateDeclaration())
|
||||
return ad->availableExternally;
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym)
|
||||
{
|
||||
if (needsTemplateLinkage(sym))
|
||||
if (needsTemplateLinkage(sym)) {
|
||||
#if LLVM_REV >= 68940
|
||||
if (isAvailableExternally(sym) && mustDefineSymbol(sym))
|
||||
return llvm::GlobalValue::AvailableExternallyLinkage;
|
||||
#endif
|
||||
return TEMPLATE_LINKAGE_TYPE;
|
||||
}
|
||||
else
|
||||
return llvm::GlobalValue::InternalLinkage;
|
||||
}
|
||||
|
||||
llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym)
|
||||
{
|
||||
#if LLVM_REV >= 68940
|
||||
if (isAvailableExternally(sym) && mustDefineSymbol(sym))
|
||||
return llvm::GlobalValue::AvailableExternallyLinkage;
|
||||
#endif
|
||||
if (needsTemplateLinkage(sym))
|
||||
return TEMPLATE_LINKAGE_TYPE;
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user