[pkg-d-commits] [ldc] 146/211: Map `export` visibility to LLVM DLL storage classes
Matthias Klumpp
mak at moszumanska.debian.org
Sun Apr 23 22:36:18 UTC 2017
This is an automated email from the git hooks/post-receive script.
mak pushed a commit to annotated tag v1.1.0
in repository ldc.
commit 67d5fe5624dd8476ea16adb59dec60df503bdd9b
Author: Martin <noone at nowhere.com>
Date: Wed Oct 26 15:25:38 2016 +0200
Map `export` visibility to LLVM DLL storage classes
Compatible with DMD, but restricted to Windows and functions only.
`export` functions with bodies get the dllexport attribute and will be
exported if the containing object is pulled in when linking.
Body-less `export` functions get the dllimport attribute and will be
accessed via an import table indirection, set up at runtime by the OS.
This is a temporary solution, the proper fix is a pending DMD PR, after
which LDC will need to be adapted.
---
gen/declarations.cpp | 3 +++
gen/functions.cpp | 11 ++++++++++-
gen/llvmhelpers.cpp | 8 ++++++++
tests/codegen/export.d | 19 +++++++++++++++++++
tests/codegen/export_crossModuleInlining.d | 19 +++++++++++++++++++
tests/codegen/inputs/export2.d | 1 +
6 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/gen/declarations.cpp b/gen/declarations.cpp
index 1e5d6bb..d7505c3 100644
--- a/gen/declarations.cpp
+++ b/gen/declarations.cpp
@@ -356,6 +356,7 @@ public:
setLinkage(lwc, newGvar);
newGvar->setAlignment(gvar->getAlignment());
+ newGvar->setDLLStorageClass(gvar->getDLLStorageClass());
applyVarDeclUDAs(decl, newGvar);
newGvar->takeName(gvar);
@@ -368,6 +369,8 @@ public:
irGlobal->value = newGvar;
}
+ assert(!gvar->hasDLLImportStorageClass());
+
// Now, set the initializer.
assert(!irGlobal->constInit);
irGlobal->constInit = initVal;
diff --git a/gen/functions.cpp b/gen/functions.cpp
index 840e8c3..44328e3 100644
--- a/gen/functions.cpp
+++ b/gen/functions.cpp
@@ -538,6 +538,12 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
func->setCallingConv(gABI->callingConv(func->getFunctionType(), link, fdecl));
+ if (global.params.isWindows && fdecl->isExport()) {
+ func->setDLLStorageClass(fdecl->isImportedSymbol()
+ ? LLGlobalValue::DLLImportStorageClass
+ : LLGlobalValue::DLLExportStorageClass);
+ }
+
IF_LOG Logger::cout() << "func = " << *func << std::endl;
// add func to IRFunc
@@ -906,11 +912,12 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
const auto f = static_cast<TypeFunction *>(fd->type->toBasetype());
IrFuncTy &irFty = irFunc->irFty;
- llvm::Function *func = irFunc->func;;
+ llvm::Function *func = irFunc->func;
const auto lwc = lowerFuncLinkage(fd);
if (linkageAvailableExternally) {
func->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
+ func->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
// Assert that we are not overriding a linkage type that disallows inlining
assert(lwc.first != llvm::GlobalValue::WeakAnyLinkage &&
lwc.first != llvm::GlobalValue::ExternalWeakLinkage &&
@@ -919,6 +926,8 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
setLinkage(lwc, func);
}
+ assert(!func->hasDLLImportStorageClass());
+
// On x86_64, always set 'uwtable' for System V ABI compatibility.
// TODO: Find a better place for this.
// TODO: Is this required for Win64 as well?
diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp
index b8b017e..132a5df 100644
--- a/gen/llvmhelpers.cpp
+++ b/gen/llvmhelpers.cpp
@@ -851,6 +851,14 @@ void DtoResolveVariable(VarDeclaration *vd) {
// as well).
gvar->setAlignment(DtoAlignment(vd));
+ /* TODO: set DLL storage class when `export` is fixed (an attribute)
+ if (global.params.isWindows && vd->isExport()) {
+ auto c = vd->isImportedSymbol() ? LLGlobalValue::DLLImportStorageClass
+ : LLGlobalValue::DLLExportStorageClass;
+ gvar->setDLLStorageClass(c);
+ }
+ */
+
applyVarDeclUDAs(vd, gvar);
IF_LOG Logger::cout() << *gvar << '\n';
diff --git a/tests/codegen/export.d b/tests/codegen/export.d
new file mode 100644
index 0000000..d53ac91
--- /dev/null
+++ b/tests/codegen/export.d
@@ -0,0 +1,19 @@
+// RUN: %ldc -output-ll -of=%t.ll %s
+// RUN: FileCheck %s < %t.ll
+
+// REQUIRES: Windows
+
+export
+{
+ // CHECK-DAG: define dllexport {{.*}}_D6export11exportedFooFZv
+ void exportedFoo() {}
+
+ // CHECK-DAG: declare dllimport {{.*}}_D6export11importedFooFZv
+ void importedFoo();
+}
+
+void bar()
+{
+ exportedFoo();
+ importedFoo();
+}
diff --git a/tests/codegen/export_crossModuleInlining.d b/tests/codegen/export_crossModuleInlining.d
new file mode 100644
index 0000000..547d2be
--- /dev/null
+++ b/tests/codegen/export_crossModuleInlining.d
@@ -0,0 +1,19 @@
+// Make sure exported functions can be cross-module inlined without exporting the local function copy.
+
+// REQUIRES: atleast_llvm307
+
+// RUN: %ldc -O -release -enable-cross-module-inlining -output-ll -of=%t.ll -I%S/inputs %s
+// RUN: FileCheck %s < %t.ll
+
+import export2;
+
+// CHECK-NOT: _D7export23fooFZi
+
+// CHECK: define {{.*}}_D26export_crossModuleInlining3barFZi
+int bar()
+{
+ // CHECK-NEXT: ret i32 666
+ return foo();
+}
+
+// CHECK-NOT: _D7export23fooFZi
diff --git a/tests/codegen/inputs/export2.d b/tests/codegen/inputs/export2.d
new file mode 100644
index 0000000..7f92355
--- /dev/null
+++ b/tests/codegen/inputs/export2.d
@@ -0,0 +1 @@
+export int foo() { return 666; }
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git
More information about the pkg-d-commits
mailing list