clover: Add CL_PROGRAM_BINARY_TYPE support (CL1.2).
authorSerge Martin <edb+mesa@sigluy.net>
Mon, 31 Oct 2016 00:21:15 +0000 (17:21 -0700)
committerSerge Martin <edb@sigluy.net>
Sun, 6 Nov 2016 14:56:54 +0000 (15:56 +0100)
v3 [Francisco Jerez]: Loosely based on Serge's v1 of this patch in
   order to avoid CL-specific enums in the clover module binary
   format.  In addition to other changes made in v2: Represent the CL
   program binary type as the section type instead of adding a CL
   API-specific enum, check that the binary types of the input objects
   are valid during clLinkProgram(), pass section type as argument to
   build_module_library() instead of using separate function.

Reviewed-by: Francisco Jerez <currojerez@riseup.net>
src/gallium/state_trackers/clover/api/program.cpp
src/gallium/state_trackers/clover/core/kernel.cpp
src/gallium/state_trackers/clover/core/module.hpp
src/gallium/state_trackers/clover/core/program.cpp
src/gallium/state_trackers/clover/core/program.hpp
src/gallium/state_trackers/clover/llvm/codegen.hpp
src/gallium/state_trackers/clover/llvm/codegen/bitcode.cpp
src/gallium/state_trackers/clover/llvm/codegen/common.cpp
src/gallium/state_trackers/clover/llvm/invocation.cpp
src/gallium/state_trackers/clover/tgsi/compiler.cpp

index ba4ce7a0c4aa00fd47e9a59d825528ba01d46158..9d59668f8f66385ccdef5d9de440dfceff01bc92 100644 (file)
@@ -248,7 +248,9 @@ namespace {
 
       for (auto &dev : all_devs) {
          const auto has_binary = [&](const program &prog) {
-            return !prog.build(dev).binary.secs.empty();
+            const auto t = prog.build(dev).binary_type();
+            return t == CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT ||
+                   t == CL_PROGRAM_BINARY_TYPE_LIBRARY;
          };
 
          // According to the CL 1.2 spec, when "all programs specified [..]
@@ -405,6 +407,10 @@ clGetProgramBuildInfo(cl_program d_prog, cl_device_id d_dev,
       buf.as_string() = prog.build(dev).log;
       break;
 
+   case CL_PROGRAM_BINARY_TYPE:
+      buf.as_scalar<cl_program_binary_type>() = prog.build(dev).binary_type();
+      break;
+
    default:
       throw error(CL_INVALID_VALUE);
    }
index 962f55507f66ee31c2b4705c5ec7febfd20e6179..471670532317f28077193f3871341c4ad9233f49 100644 (file)
@@ -162,7 +162,7 @@ kernel::exec_context::bind(intrusive_ptr<command_queue> _q,
    // Bind kernel arguments.
    auto &m = kern.program().build(q->device()).binary;
    auto margs = find(name_equals(kern.name()), m.syms).args;
-   auto msec = find(type_equals(module::section::text), m.secs);
+   auto msec = find(type_equals(module::section::text_executable), m.secs);
    auto explicit_arg = kern._args.begin();
 
    for (auto &marg : margs) {
index 5db0548872c921c680cbe805340eb18b1ff5e0e1..2ddd26426fbd95dd24385ad2e1de2c7b245f08f5 100644 (file)
@@ -33,7 +33,9 @@ namespace clover {
 
       struct section {
          enum type {
-            text,
+            text_intermediate,
+            text_library,
+            text_executable,
             data_constant,
             data_global,
             data_local,
@@ -43,7 +45,7 @@ namespace clover {
          section(resource_id id, enum type type, size_t size,
                  const std::vector<char> &data) :
                  id(id), type(type), size(size), data(data) { }
-         section() : id(0), type(text), size(0), data() { }
+         section() : id(0), type(text_intermediate), size(0), data() { }
 
          resource_id id;
          type type;
index 79ac85117e33cba71e12d4e5c8cb89b55b2e70a2..ae4b50a8797a985696ccde1b15593d4bf4665a22 100644 (file)
@@ -108,6 +108,18 @@ program::build::status() const {
       return CL_BUILD_NONE;
 }
 
+cl_program_binary_type
+program::build::binary_type() const {
+   if (any_of(type_equals(module::section::text_intermediate), binary.secs))
+      return CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
+   else if (any_of(type_equals(module::section::text_library), binary.secs))
+      return CL_PROGRAM_BINARY_TYPE_LIBRARY;
+   else if (any_of(type_equals(module::section::text_executable), binary.secs))
+      return CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
+   else
+      return CL_PROGRAM_BINARY_TYPE_NONE;
+}
+
 const struct program::build &
 program::build(const device &dev) const {
    static const struct build null;
index 76f16d2f9f1d1d5fb2783bdb8457213ba0e8c5f6..05964e78a79a9da609ae40ca24fa1f30139352bd 100644 (file)
@@ -63,6 +63,7 @@ namespace clover {
                const std::string &log = {}) : binary(m), opts(opts), log(log) {}
 
          cl_build_status status() const;
+         cl_program_binary_type binary_type() const;
 
          module binary;
          std::string opts;
index e0e990190d28026ebd9107641a96d082d6c08d1e..44971adb7dd86185754b5123ad45a0ef4946db02 100644 (file)
@@ -46,7 +46,8 @@ namespace clover {
       print_module_bitcode(const ::llvm::Module &mod);
 
       module
-      build_module_library(const ::llvm::Module &mod);
+      build_module_library(const ::llvm::Module &mod,
+                           enum module::section::type section_type);
 
       std::unique_ptr<::llvm::Module>
       parse_module_library(const module &m, ::llvm::LLVMContext &ctx,
index 658cce923c97639687bc4ea3a46d99a07d15f5ad..108f8d54e9e5bdad300d7c545a5a937aa41dcee3 100644 (file)
@@ -80,10 +80,11 @@ clover::llvm::print_module_bitcode(const ::llvm::Module &mod) {
 }
 
 module
-clover::llvm::build_module_library(const ::llvm::Module &mod) {
+clover::llvm::build_module_library(const ::llvm::Module &mod,
+                                   enum module::section::type section_type) {
    module m;
    const auto code = emit_code(mod);
-   m.secs.emplace_back(0, module::section::text, code.size(), code);
+   m.secs.emplace_back(0, section_type, code.size(), code);
    return m;
 }
 
index 834b06a134cf9f7902783f0af263397309874b71..13ccd591c117f0e699a301b5e2c64304cce228ab 100644 (file)
@@ -179,7 +179,8 @@ namespace {
    module::section
    make_text_section(const std::vector<char> &code) {
       const pipe_llvm_program_header header { uint32_t(code.size()) };
-      module::section text { 0, module::section::text, header.num_bytes, {} };
+      module::section text { 0, module::section::text_executable,
+                             header.num_bytes, {} };
 
       text.data.insert(text.data.end(), reinterpret_cast<const char *>(&header),
                        reinterpret_cast<const char *>(&header) + sizeof(header));
index b5e8b523fabc0616feb829ecd6079879929ade0a..675cf1944d75839a22f057b232ceaf7952ab90fc 100644 (file)
@@ -211,7 +211,7 @@ clover::llvm::compile_program(const std::string &source,
    if (has_flag(debug::llvm))
       debug::log(".ll", print_module_bitcode(*mod));
 
-   return build_module_library(*mod);
+   return build_module_library(*mod, module::section::text_intermediate);
 }
 
 namespace {
@@ -280,7 +280,7 @@ clover::llvm::link_program(const std::vector<module> &modules,
       debug::log(".ll", print_module_bitcode(*mod));
 
    if (create_library) {
-      return build_module_library(*mod);
+      return build_module_library(*mod, module::section::text_library);
 
    } else if (ir == PIPE_SHADER_IR_LLVM) {
       return build_module_bitcode(*mod, *c);
index 9bbd4541e9bc063ced91ba940291699a4f011d71..e165311fa415de5892266c81926ad4ce56de3274 100644 (file)
@@ -91,7 +91,7 @@ namespace {
 
       unsigned sz = tgsi_num_tokens(prog) * sizeof(tgsi_token);
       std::vector<char> data( (char *)prog, (char *)prog + sz );
-      m.secs.push_back({ 0, module::section::text, sz, data });
+      m.secs.push_back({ 0, module::section::text_executable, sz, data });
    }
 }