clover/llvm: Implement the -create-library linker option.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 3 Jun 2016 22:46:21 +0000 (15:46 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Tue, 12 Jul 2016 03:34:34 +0000 (20:34 -0700)
[ Serge Martin: disable internalize pass when building a library.
  Otherwise some functions may be inlined and removed ]

Reviewed-by: Serge Martin <edb+mesa@sigluy.net>
Tested-by: Jan Vesely <jan.vesely@rutgers.edu>
src/gallium/state_trackers/clover/llvm/invocation.cpp
src/gallium/state_trackers/clover/util/functional.hpp

index 6560b89d1f54607abb8770f397048a3ff12ef833..40b00b7ef1302b83fe389ae035ead80e2023a47b 100644 (file)
@@ -202,7 +202,8 @@ clover::llvm::compile_program(const std::string &source,
 
 namespace {
    void
-   optimize(Module &mod, unsigned optimization_level) {
+   optimize(Module &mod, unsigned optimization_level,
+            bool internalize_symbols) {
       compat::pass_manager pm;
 
       compat::add_data_layout_pass(pm);
@@ -219,8 +220,9 @@ namespace {
       // 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.
-      compat::add_internalize_pass(pm, map(std::mem_fn(&Function::getName),
-                                           get_kernels(mod)));
+      if (internalize_symbols)
+         compat::add_internalize_pass(pm, map(std::mem_fn(&Function::getName),
+                                              get_kernels(mod)));
 
       ::llvm::PassManagerBuilder pmb;
       pmb.OptLevel = optimization_level;
@@ -251,36 +253,33 @@ clover::llvm::link_program(const std::vector<module> &modules,
                            enum pipe_shader_ir ir, const std::string &target,
                            const std::string &opts, std::string &r_log) {
    std::vector<std::string> options = tokenize(opts + " input.cl");
+   const bool create_library = count("-create-library", options);
+   erase_if(equals("-create-library"), options);
+
    auto ctx = create_context(r_log);
    auto c = create_compiler_instance(target, options, r_log);
    auto mod = link(*ctx, *c, modules, r_log);
 
-   optimize(*mod, c->getCodeGenOpts().OptimizationLevel);
+   optimize(*mod, c->getCodeGenOpts().OptimizationLevel, !create_library);
 
    if (has_flag(debug::llvm))
       debug::log(".ll", print_module_bitcode(*mod));
 
-   module m;
-   // Build the clover::module
-   switch (ir) {
-      case PIPE_SHADER_IR_NIR:
-      case PIPE_SHADER_IR_TGSI:
-         //XXX: Handle TGSI, NIR
-         assert(0);
-         m = module();
-         break;
-      case PIPE_SHADER_IR_LLVM:
-         m = build_module_bitcode(*mod, *c);
-         break;
-      case PIPE_SHADER_IR_NATIVE:
-         if (has_flag(debug::native))
-            debug::log(".asm", print_module_native(*mod, target));
-
-         m = build_module_native(*mod, target, *c, r_log);
-         break;
-   }
+   if (create_library) {
+      return build_module_library(*mod);
+
+   } else if (ir == PIPE_SHADER_IR_LLVM) {
+      return build_module_bitcode(*mod, *c);
 
-   return m;
+   } else if (ir == PIPE_SHADER_IR_NATIVE) {
+      if (has_flag(debug::native))
+         debug::log(".asm", print_module_native(*mod, target));
+
+      return build_module_native(*mod, target, *c, r_log);
+
+   } else {
+      unreachable("Unsupported IR.");
+   }
 }
 
 module
index ed69155c45b2f1ccb09da9b71b336ca789c4265a..98bbdff4bd1044e3fc5be064b84ae97ab887bfab 100644 (file)
@@ -311,6 +311,27 @@ namespace clover {
       }
    };
 
+   template<typename T>
+   class equals_t {
+   public:
+      equals_t(T &&x) : x(x) {}
+
+      template<typename S>
+      bool
+      operator()(S &&y) const {
+         return x == y;
+      }
+
+   private:
+      T x;
+   };
+
+   template<typename T>
+   equals_t<T>
+   equals(T &&x) {
+      return { std::forward<T>(x) };
+   }
+
    class name_equals {
    public:
       name_equals(const std::string &name) : name(name) {