clover/llvm: Implement linkage of multiple clover modules.
authorFrancisco Jerez <currojerez@riseup.net>
Mon, 13 Jun 2016 08:41:05 +0000 (01:41 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Tue, 12 Jul 2016 03:34:34 +0000 (20:34 -0700)
Reviewed-by: Serge Martin <edb+mesa@sigluy.net>
Tested-by: Jan Vesely <jan.vesely@rutgers.edu>
src/gallium/state_trackers/clover/llvm/compat.hpp
src/gallium/state_trackers/clover/llvm/invocation.cpp

index 82dd649..a963cff 100644 (file)
@@ -113,6 +113,25 @@ namespace clover {
 #endif
          }
 
+         inline std::unique_ptr<::llvm::Linker>
+         create_linker(::llvm::Module &mod) {
+#if HAVE_LLVM >= 0x0308
+            return std::unique_ptr<::llvm::Linker>(new ::llvm::Linker(mod));
+#else
+            return std::unique_ptr<::llvm::Linker>(new ::llvm::Linker(&mod));
+#endif
+         }
+
+         inline bool
+         link_in_module(::llvm::Linker &linker,
+                        std::unique_ptr<::llvm::Module> mod) {
+#if HAVE_LLVM >= 0x0308
+            return linker.linkInModule(std::move(mod));
+#else
+            return linker.linkInModule(mod.get());
+#endif
+         }
+
 #if HAVE_LLVM >= 0x0307
          typedef ::llvm::raw_svector_ostream &raw_ostream_to_emit_file;
 #else
index 3bb7d72..6560b89 100644 (file)
@@ -229,6 +229,21 @@ namespace {
       pmb.populateModulePassManager(pm);
       pm.run(mod);
    }
+
+   std::unique_ptr<Module>
+   link(LLVMContext &ctx, const clang::CompilerInstance &c,
+        const std::vector<module> &modules, std::string &r_log) {
+      std::unique_ptr<Module> mod { new Module("link", ctx) };
+      auto linker = compat::create_linker(*mod);
+
+      for (auto &m : modules) {
+         if (compat::link_in_module(*linker,
+                                    parse_module_library(m, ctx, r_log)))
+            throw compile_error();
+      }
+
+      return std::move(mod);
+   }
 }
 
 module
@@ -238,9 +253,7 @@ clover::llvm::link_program(const std::vector<module> &modules,
    std::vector<std::string> options = tokenize(opts + " input.cl");
    auto ctx = create_context(r_log);
    auto c = create_compiler_instance(target, options, r_log);
-   // XXX - Implement linkage of multiple clover modules.
-   assert(modules.size() == 1);
-   auto mod = parse_module_library(modules[0], *ctx, r_log);
+   auto mod = link(*ctx, *c, modules, r_log);
 
    optimize(*mod, c->getCodeGenOpts().OptimizationLevel);