[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