[Mesa-dev] [PATCH v7 7/7] clover: add -create-library option support

Serge Martin edb+mesa at sigluy.net
Sat Feb 13 22:08:41 UTC 2016


---
 .../state_trackers/clover/llvm/invocation.cpp      | 87 ++++++++++++----------
 .../state_trackers/clover/llvm/ir_compiler.cpp     | 46 +++++++++---
 .../state_trackers/clover/llvm/ir_compiler.hpp     |  4 +-
 3 files changed, 85 insertions(+), 52 deletions(-)

diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index be00b65..5b3dd1f 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -381,6 +381,24 @@ namespace {
    }
 
    module
+   serialize_to_clover_module(llvm::Module *mod) {
+      llvm::SmallVector<char, 1024> llvm_bitcode;
+      llvm::raw_svector_ostream bitcode_ostream(llvm_bitcode);
+      llvm::BitstreamWriter writer(llvm_bitcode);
+      llvm::WriteBitcodeToFile(mod, bitcode_ostream);
+#if HAVE_LLVM < 0x0308
+      bitcode_ostream.flush();
+#endif
+
+      module m;
+      std::vector<char> data(llvm_bitcode.begin(), llvm_bitcode.end());
+      m.secs.push_back(module::section(0, module::section::text,
+                                          data.size(), data));
+
+      return m;
+   }
+
+   module
    build_module_llvm(llvm::Module *mod,
                      clang::LangAS::Map& address_spaces) {
 
@@ -666,7 +684,7 @@ clover::compile_program_llvm(const std::string &source,
       throw;
    }
 
-   c.optimize();
+   c.optimize(false);
 
    r_log = c.get_log();
 
@@ -681,20 +699,7 @@ clover::compile_program_llvm(const std::string &source,
     }
 
    //serialize for later use
-   module m;
-   llvm::SmallVector<char, 1024> llvm_bitcode;
-   llvm::raw_svector_ostream bitcode_ostream(llvm_bitcode);
-   llvm::BitstreamWriter writer(llvm_bitcode);
-   llvm::WriteBitcodeToFile(mod, bitcode_ostream);
-#if HAVE_LLVM < 0x0308
-   bitcode_ostream.flush();
-#endif
-
-   std::vector<char> data(llvm_bitcode.begin(), llvm_bitcode.end());
-   m.secs.push_back(module::section(0, module::section::text,
-                                       data.size(), data));
-
-   return m;
+   return serialize_to_clover_module(mod);
 }
 
 module
@@ -718,7 +723,7 @@ clover::link_program_llvm(const std::vector<module> &modules,
       throw;
    }
 
-   c.optimize();
+   c.optimize(true);
 
    r_log = c.get_log();
 
@@ -732,30 +737,34 @@ clover::link_program_llvm(const std::vector<module> &modules,
       debug_log(log, ".ll");
     }
 
-   const clang::TargetInfo &info = c.get_info();
-   // Get address spaces map to be able to find kernel argument address space
-   clang::LangAS::Map address_spaces;
-   memcpy(address_spaces, info.getAddressSpaceMap(), sizeof(address_spaces));
-
    module m;
-   // Build the clover::module
-   switch (ir) {
-      case PIPE_SHADER_IR_TGSI:
-         //XXX: Handle TGSI
-         assert(0);
-         m = module();
-         break;
-      case PIPE_SHADER_IR_LLVM:
-         m = build_module_llvm(mod, address_spaces);
-         break;
-      case PIPE_SHADER_IR_NATIVE: {
-         std::vector<char> code = compile_native(mod,
-                                                 info.getTargetOpts().Triple,
-                                                 info.getTargetOpts().CPU,
-                                                 get_debug_flags() & DBG_ASM,
-                                                 r_log);
-         m = build_module_native(code, mod, address_spaces, r_log);
-         break;
+   if (c.as_library()) {
+      m = serialize_to_clover_module(mod);
+   } else {
+      const clang::TargetInfo &info = c.get_info();
+      // Get address spaces map to be able to find kernel argument address space
+      clang::LangAS::Map address_spaces;
+      memcpy(address_spaces, info.getAddressSpaceMap(), sizeof(address_spaces));
+
+      // Build the clover::module
+      switch (ir) {
+         case PIPE_SHADER_IR_TGSI:
+            //XXX: Handle TGSI
+            assert(0);
+            m = module();
+            break;
+         case PIPE_SHADER_IR_LLVM:
+            m = build_module_llvm(mod, address_spaces);
+            break;
+         case PIPE_SHADER_IR_NATIVE: {
+            std::vector<char> code = compile_native(mod,
+                                                    info.getTargetOpts().Triple,
+                                                    info.getTargetOpts().CPU,
+                                                    get_debug_flags() & DBG_ASM,
+                                                    r_log);
+            m = build_module_native(code, mod, address_spaces, r_log);
+            break;
+         }
       }
    }
 
diff --git a/src/gallium/state_trackers/clover/llvm/ir_compiler.cpp b/src/gallium/state_trackers/clover/llvm/ir_compiler.cpp
index 5aa77db..ebc2cb7 100644
--- a/src/gallium/state_trackers/clover/llvm/ir_compiler.cpp
+++ b/src/gallium/state_trackers/clover/llvm/ir_compiler.cpp
@@ -48,7 +48,7 @@
 static const std::string input_name("input.cl");
 
 llvm_ir_compiler::llvm_ir_compiler(llvm::LLVMContext *llvm_ctx) :
-   _llvm_ctx(llvm_ctx), _module(nullptr), _raw_log(_log) {
+   _llvm_ctx(llvm_ctx), _module(nullptr), _raw_log(_log), _as_library(false) {
 };
 
 llvm_ir_compiler::~llvm_ir_compiler() {
@@ -70,6 +70,15 @@ llvm_ir_compiler::parse_args(const std::string &target,
    while (!ss.eof()) {
       std::string opt;
       getline(ss, opt, ' ');
+
+      if (opt == "-create-library") {
+         if (error_kind != CL_INVALID_LINKER_OPTIONS)
+            throw clover::error(error_kind);
+
+         _as_library = true;
+         continue;
+      }
+
       opts_array.push_back(opt);
    }
 
@@ -239,9 +248,12 @@ llvm_ir_compiler::link(const std::vector<clover::module> &modules) {
 }
 
 void
-llvm_ir_compiler::optimize() {
+llvm_ir_compiler::optimize(bool allow_internalizer) {
    assert(_module);
 
+   if (_as_library)
+      allow_internalizer = false;
+
 #if HAVE_LLVM >= 0x0307
    llvm::legacy::PassManager PM;
 #else
@@ -262,20 +274,24 @@ llvm_ir_compiler::optimize() {
    // list of kernel functions to the internalizer.  The internalizer will
    // treat the functions in the list as "main" functions and internalize
    // all of the other functions.
+   //
+   // This is disable for library
    std::vector<const char*> export_list;
 
-   const llvm::NamedMDNode *kernel_node =
-                                    _module->getNamedMetadata("opencl.kernels");
-   if (kernel_node) {
-      export_list.reserve(kernel_node->getNumOperands());
-      for (unsigned i = 0; i < kernel_node->getNumOperands(); ++i) {
+   if (allow_internalizer) {
+      const llvm::NamedMDNode *kernel_node =
+                                       _module->getNamedMetadata("opencl.kernels");
+      if (kernel_node) {
+         export_list.reserve(kernel_node->getNumOperands());
+         for (unsigned i = 0; i < kernel_node->getNumOperands(); ++i) {
 #if HAVE_LLVM >= 0x0306
-         llvm::Function *kernel = llvm::mdconst::dyn_extract<llvm::Function>(
+            llvm::Function *kernel = llvm::mdconst::dyn_extract<llvm::Function>(
 #else
-         llvm::Function *kernel = llvm::dyn_cast<llvm::Function>(
+            llvm::Function *kernel = llvm::dyn_cast<llvm::Function>(
 #endif
-                                    kernel_node->getOperand(i)->getOperand(0));
-         export_list.push_back(kernel->getName().data());
+                                       kernel_node->getOperand(i)->getOperand(0));
+            export_list.push_back(kernel->getName().data());
+         }
       }
    }
 
@@ -285,7 +301,8 @@ llvm_ir_compiler::optimize() {
    PM.add(new llvm::DataLayoutPass());
 #endif
 
-   PM.add(llvm::createInternalizePass(export_list));
+   if (allow_internalizer)
+      PM.add(llvm::createInternalizePass(export_list));
 
    llvm::PassManagerBuilder PMB;
    PMB.OptLevel = _ci.getCodeGenOpts().OptimizationLevel;
@@ -313,3 +330,8 @@ llvm::Module *
 llvm_ir_compiler::get_module() const {
    return _module;
 }
+
+bool
+llvm_ir_compiler::as_library() const {
+   return _as_library;
+}
diff --git a/src/gallium/state_trackers/clover/llvm/ir_compiler.hpp b/src/gallium/state_trackers/clover/llvm/ir_compiler.hpp
index b8b9ce3..1564488 100644
--- a/src/gallium/state_trackers/clover/llvm/ir_compiler.hpp
+++ b/src/gallium/state_trackers/clover/llvm/ir_compiler.hpp
@@ -44,11 +44,12 @@ public:
                    cl_int error_kind);
    void compile(const std::string &source, const header_map &headers);
    void link(const std::vector<clover::module> &modules);
-   void optimize();
+   void optimize(bool allow_internalizer);
 
    const clang::TargetInfo &get_info() const;
    std::string get_log() const;
    llvm::Module *get_module() const;
+   bool as_library() const;
 
 private:
    llvm::LLVMContext *_llvm_ctx;
@@ -58,6 +59,7 @@ private:
 
    std::string _log;
    llvm::raw_string_ostream _raw_log;
+   bool _as_library;
 };
 
 #endif
-- 
2.5.0



More information about the mesa-dev mailing list