[pkg-d-commits] [ldc] 115/211: Only emit llvm.used _once_ when compiling multiple D modules into one LLVM module.

Matthias Klumpp mak at moszumanska.debian.org
Sun Apr 23 22:36:15 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 7deae74d89138244d22f0f318166048c3af33502
Author: Johan Engelen <jbc.engelen at gmail.com>
Date:   Wed Oct 26 10:13:26 2016 +0900

    Only emit llvm.used _once_ when compiling multiple D modules into one LLVM module.
---
 driver/codegenerator.cpp           | 21 +++++++++++++++++++++
 gen/declarations.cpp               |  2 +-
 gen/modules.cpp                    | 22 ----------------------
 tests/codegen/inputs/module_ctor.d |  6 ++++++
 tests/codegen/llvm_used_1.d        | 26 ++++++++++++++++++++++++++
 5 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/driver/codegenerator.cpp b/driver/codegenerator.cpp
index 2ee78a4..d2b4fd0 100644
--- a/driver/codegenerator.cpp
+++ b/driver/codegenerator.cpp
@@ -73,6 +73,26 @@ void emitLinkerOptions(IRState &irs, llvm::Module &M, llvm::LLVMContext &ctx) {
 #endif
   }
 }
+
+void emitLLVMUsedArray(IRState &irs) {
+  if (irs.usedArray.empty()) {
+    return;
+  }
+
+  auto *i8PtrType = llvm::Type::getInt8PtrTy(irs.context());
+
+  // Convert all elements to i8* (the expected type for llvm.used)
+  for (auto &elem : irs.usedArray) {
+    elem = llvm::ConstantExpr::getBitCast(elem, i8PtrType);
+  }
+
+  auto *arrayType = llvm::ArrayType::get(i8PtrType, irs.usedArray.size());
+  auto *llvmUsed = new llvm::GlobalVariable(
+      irs.module, arrayType, false, llvm::GlobalValue::AppendingLinkage,
+      llvm::ConstantArray::get(arrayType, irs.usedArray), "llvm.used");
+  llvmUsed->setSection("llvm.metadata");
+}
+
 }
 
 namespace ldc {
@@ -153,6 +173,7 @@ void CodeGenerator::finishLLModule(Module *m) {
 void CodeGenerator::writeAndFreeLLModule(const char *filename) {
   ir_->DBuilder.Finalize();
 
+  emitLLVMUsedArray(*ir_);
   emitLinkerOptions(*ir_, ir_->module, ir_->context());
 
   // Emit ldc version as llvm.ident metadata.
diff --git a/gen/declarations.cpp b/gen/declarations.cpp
index c3ceff4..1e5d6bb 100644
--- a/gen/declarations.cpp
+++ b/gen/declarations.cpp
@@ -382,7 +382,7 @@ public:
       // artificial "use" for it, or it could be removed by the optimizer if
       // the only reference to it is in inline asm.
       if (irGlobal->nakedUse) {
-        irs->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType()));
+        irs->usedArray.push_back(gvar);
       }
 
       IF_LOG Logger::cout() << *gvar << '\n';
diff --git a/gen/modules.cpp b/gen/modules.cpp
index 3545ce1..a4eb36d 100644
--- a/gen/modules.cpp
+++ b/gen/modules.cpp
@@ -484,26 +484,6 @@ void emitModuleRefToSection(RegistryStyle style, std::string moduleMangle,
   llvm::appendToGlobalDtors(gIR->module, dsoDtor, 65535);
 }
 
-void build_llvm_used_array(IRState *p) {
-  if (p->usedArray.empty()) {
-    return;
-  }
-
-  std::vector<llvm::Constant *> usedVoidPtrs;
-  usedVoidPtrs.reserve(p->usedArray.size());
-
-  for (auto constant : p->usedArray) {
-    usedVoidPtrs.push_back(DtoBitCast(constant, getVoidPtrType()));
-  }
-
-  llvm::ArrayType *arrayType =
-      llvm::ArrayType::get(getVoidPtrType(), usedVoidPtrs.size());
-  auto llvmUsed = new llvm::GlobalVariable(
-      p->module, arrayType, false, llvm::GlobalValue::AppendingLinkage,
-      llvm::ConstantArray::get(arrayType, usedVoidPtrs), "llvm.used");
-  llvmUsed->setSection("llvm.metadata");
-}
-
 // Add module-private variables and functions for coverage analysis.
 void addCoverageAnalysis(Module *m) {
   IF_LOG {
@@ -746,8 +726,6 @@ void codegenModule(IRState *irs, Module *m) {
   if (!m->noModuleInfo) {
     // generate ModuleInfo
     registerModuleInfo(m);
-
-    build_llvm_used_array(irs);
   }
 
   if (m->d_cover_valid) {
diff --git a/tests/codegen/inputs/module_ctor.d b/tests/codegen/inputs/module_ctor.d
new file mode 100644
index 0000000..3a0f996
--- /dev/null
+++ b/tests/codegen/inputs/module_ctor.d
@@ -0,0 +1,6 @@
+import core.stdc.stdio;
+
+static this()
+{
+    puts("ctor\n");
+}
diff --git a/tests/codegen/llvm_used_1.d b/tests/codegen/llvm_used_1.d
new file mode 100644
index 0000000..31fae6d
--- /dev/null
+++ b/tests/codegen/llvm_used_1.d
@@ -0,0 +1,26 @@
+// Test that llvm.used is emitted correctly when multiple D modules are compiled into one LLVM module.
+
+// Explicitly use OS X triple, so that llvm.used is used for moduleinfo globals.
+// RUN: %ldc -c -output-ll -O3 %S/inputs/module_ctor.d %s -of=%t.ll -mtriple=x86_64-apple-macosx && FileCheck --check-prefix=LLVM %s < %t.ll
+
+// RUN: %ldc -O3 %S/inputs/module_ctor.d -run %s | FileCheck --check-prefix=EXECUTE %s
+
+// There was a bug where llvm.used was emitted more than once, whose symptom was that suffixed versions would appear: e.g. `@llvm.used.3`.
+// LLVM-NOT: @llvm.used.
+// LLVM: @llvm.used = appending global [2 x i8*]
+// LLVM-NOT: @llvm.used.
+
+// EXECUTE: ctor
+// EXECUTE: main
+// EXECUTE: dtor
+
+import core.stdc.stdio;
+
+static ~this()
+{
+    puts("dtor\n");
+}
+
+void main() {
+    puts("main\n");
+}
\ No newline at end of file

-- 
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