[Mesa-dev] [PATCH v2] clover: add GetKernelArgInfo (CL 1.2)

Serge Martin edb+mesa at sigluy.net
Sat Oct 1 13:54:49 UTC 2016


---
 src/gallium/state_trackers/clover/api/kernel.cpp   | 47 ++++++++++++++++--
 src/gallium/state_trackers/clover/core/kernel.cpp  |  6 +++
 src/gallium/state_trackers/clover/core/kernel.hpp  |  1 +
 src/gallium/state_trackers/clover/core/module.hpp  | 19 +++++--
 .../state_trackers/clover/llvm/codegen/common.cpp  | 58 +++++++++++++++++++++-
 .../state_trackers/clover/llvm/metadata.hpp        | 16 ++++++
 .../state_trackers/clover/tgsi/compiler.cpp        |  2 +-
 7 files changed, 141 insertions(+), 8 deletions(-)

diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp
index 73ba34a..13cfc08 100644
--- a/src/gallium/state_trackers/clover/api/kernel.cpp
+++ b/src/gallium/state_trackers/clover/api/kernel.cpp
@@ -192,9 +192,50 @@ clGetKernelWorkGroupInfo(cl_kernel d_kern, cl_device_id d_dev,
 CLOVER_API cl_int
 clGetKernelArgInfo(cl_kernel d_kern,
                    cl_uint idx, cl_kernel_arg_info param,
-                   size_t size, void *r_buf, size_t *r_size) {
-   CLOVER_NOT_SUPPORTED_UNTIL("1.2");
-   return CL_KERNEL_ARG_INFO_NOT_AVAILABLE;
+                   size_t size, void *r_buf, size_t *r_size) try {
+   property_buffer buf { r_buf, size, r_size };
+   const auto &kern = obj(d_kern);
+   const auto args_info = kern.args_info();
+
+   if (args_info.size() == 0)
+      throw error(CL_KERNEL_ARG_INFO_NOT_AVAILABLE);
+
+   if (idx >= args_info.size())
+      throw error(CL_INVALID_ARG_INDEX);
+
+   const auto &info = args_info[idx];
+
+   switch (param) {
+   case CL_KERNEL_ARG_ADDRESS_QUALIFIER:
+      buf.as_scalar<cl_kernel_arg_address_qualifier>() =
+                                                      info.address_qualifier;
+      break;
+
+   case CL_KERNEL_ARG_ACCESS_QUALIFIER:
+      buf.as_scalar<cl_kernel_arg_access_qualifier>() =
+                                                      info.access_qualifier;
+      break;
+
+   case CL_KERNEL_ARG_TYPE_NAME:
+      buf.as_string() = info.type_name;
+      break;
+
+   case CL_KERNEL_ARG_TYPE_QUALIFIER:
+      buf.as_scalar<cl_kernel_arg_type_qualifier>() = info.type_qualifier;
+      break;
+
+   case CL_KERNEL_ARG_NAME:
+      buf.as_string() = info.arg_name;
+      break;
+
+   default:
+      throw error(CL_INVALID_VALUE);
+   }
+
+   return CL_SUCCESS;
+
+} catch (error &e) {
+   return e.get();
 }
 
 namespace {
diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp
index 962f555..18dcd5c 100644
--- a/src/gallium/state_trackers/clover/core/kernel.cpp
+++ b/src/gallium/state_trackers/clover/core/kernel.cpp
@@ -140,6 +140,12 @@ kernel::args() const {
    return map(derefs(), _args);
 }
 
+std::vector<clover::module::argument_info>
+kernel::args_info() const {
+   const auto &syms = program().symbols();
+   return find(name_equals(_name), syms).args_info;
+}
+
 const module &
 kernel::module(const command_queue &q) const {
    return program().build(q.device()).binary;
diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp
index 4ba6ff4..aae51bc 100644
--- a/src/gallium/state_trackers/clover/core/kernel.hpp
+++ b/src/gallium/state_trackers/clover/core/kernel.hpp
@@ -134,6 +134,7 @@ namespace clover {
 
       argument_range args();
       const_argument_range args() const;
+      std::vector<clover::module::argument_info> args_info() const;
 
       const intrusive_ref<clover::program> program;
 
diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp
index 5db0548..5ce9492 100644
--- a/src/gallium/state_trackers/clover/core/module.hpp
+++ b/src/gallium/state_trackers/clover/core/module.hpp
@@ -102,16 +102,29 @@ namespace clover {
          semantic semantic;
       };
 
+      struct argument_info {
+         argument_info() { }
+
+         uint32_t address_qualifier;
+         uint32_t access_qualifier;
+         std::string type_name;
+         uint32_t type_qualifier;
+         std::string arg_name;
+      };
+
       struct symbol {
          symbol(const std::string &name, resource_id section,
-                size_t offset, const std::vector<argument> &args) :
-                name(name), section(section), offset(offset), args(args) { }
-         symbol() : name(), section(0), offset(0), args() { }
+                size_t offset, const std::vector<argument> &args,
+                const std::vector<argument_info> &args_info) :
+                name(name), section(section), offset(offset),
+                args(args), args_info(args_info) { }
+         symbol() : name(), section(0), offset(0), args(), args_info() { }
 
          std::string name;
          resource_id section;
          size_t offset;
          std::vector<argument> args;
+         std::vector<argument_info> args_info;
       };
 
       void serialize(std::ostream &os) const;
diff --git a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
index 834b06a..07f45f9 100644
--- a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
+++ b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
@@ -66,6 +66,60 @@ namespace {
          unreachable("Unknown image type");
    }
 
+   std::vector<module::argument_info>
+   make_args_infos(const Module &mod, const std::string &kernel_name,
+                   const bool has_args_infos) {
+      if (!has_args_infos)
+         return {};
+
+      const Function &f = *mod.getFunction(kernel_name);
+
+      std::vector<module::argument_info> infos;
+      for (const auto &arg : f.args()) {
+         module::argument_info info;
+
+         const auto addr_space = get_uint_argument_metadata(f, arg,
+                                                      "kernel_arg_addr_space");
+         if (addr_space == 0)
+            info.address_qualifier = CL_KERNEL_ARG_ADDRESS_PRIVATE;
+         else if (addr_space == 1)
+            info.address_qualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL;
+         else if (addr_space == 2)
+            info.address_qualifier = CL_KERNEL_ARG_ADDRESS_CONSTANT;
+         else if (addr_space == 3)
+            info.address_qualifier = CL_KERNEL_ARG_ADDRESS_LOCAL;
+
+         const auto access_qual = get_argument_metadata(f, arg,
+                                                      "kernel_arg_access_qual");
+         if (access_qual == "read_only")
+            info.access_qualifier = CL_KERNEL_ARG_ACCESS_READ_ONLY;
+         else if (access_qual == "write_only")
+            info.access_qualifier = CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
+         else if (access_qual == "read_write")
+            info.access_qualifier = CL_KERNEL_ARG_ACCESS_READ_WRITE;
+         else if (access_qual == "none")
+            info.access_qualifier = CL_KERNEL_ARG_ACCESS_NONE;
+
+         info.type_name = get_argument_metadata(f, arg, "kernel_arg_type");
+
+         const auto type_qual = get_argument_metadata(f, arg,
+                                                         "kernel_arg_type_qual");
+         info.type_qualifier = CL_KERNEL_ARG_TYPE_NONE;
+         if (type_qual.find("const") != std::string::npos)
+            info.type_qualifier |= CL_KERNEL_ARG_TYPE_CONST;
+         if (type_qual.find("restrict") != std::string::npos)
+            info.type_qualifier |= CL_KERNEL_ARG_TYPE_RESTRICT;
+         if (type_qual.find("volatile") != std::string::npos)
+            info.type_qualifier |= CL_KERNEL_ARG_TYPE_VOLATILE;
+
+         info.arg_name = get_argument_metadata(f, arg, "kernel_arg_name");
+
+         infos.emplace_back(info);
+      }
+
+      return infos;
+   }
+
    std::vector<module::argument>
    make_kernel_args(const Module &mod, const std::string &kernel_name,
                     const clang::CompilerInstance &c) {
@@ -196,12 +250,14 @@ clover::llvm::build_module_common(const Module &mod,
                                                  unsigned> &offsets,
                                   const clang::CompilerInstance &c) {
    module m;
+   const bool has_args_infos = c.getCodeGenOpts().EmitOpenCLArgMetadata;
 
    for (const auto &name : map(std::mem_fn(&Function::getName),
                                get_kernels(mod))) {
       if (offsets.count(name))
          m.syms.emplace_back(name, 0, offsets.at(name),
-                             make_kernel_args(mod, name, c));
+                             make_kernel_args(mod, name, c),
+                             make_args_infos(mod, name, has_args_infos));
    }
 
    m.secs.push_back(make_text_section(code));
diff --git a/src/gallium/state_trackers/clover/llvm/metadata.hpp b/src/gallium/state_trackers/clover/llvm/metadata.hpp
index 814c830..ddc5259 100644
--- a/src/gallium/state_trackers/clover/llvm/metadata.hpp
+++ b/src/gallium/state_trackers/clover/llvm/metadata.hpp
@@ -32,6 +32,7 @@
 #include "util/algorithm.hpp"
 
 #include <vector>
+#include <llvm/IR/Constants.h>
 #include <llvm/IR/Module.h>
 #include <llvm/IR/Metadata.h>
 
@@ -112,6 +113,21 @@ namespace clover {
       }
 
       ///
+      /// Extract the uint metadata node \p name corresponding to the kernel
+      /// argument given by \p arg.
+      ///
+      inline uint64_t
+      get_uint_argument_metadata(const ::llvm::Function &f,
+                                 const ::llvm::Argument &arg,
+                                 const std::string &name) {
+         return ::llvm::cast<::llvm::ConstantInt>(
+            ::llvm::dyn_cast<::llvm::ConstantAsMetadata>(
+               detail::get_kernel_metadata_operands(f, name)[arg.getArgNo()])
+               ->getValue())
+            ->getLimitedValue(UINT_MAX);
+      }
+
+      ///
       /// Return a vector with all CL kernel functions found in the LLVM
       /// module \p mod.
       ///
diff --git a/src/gallium/state_trackers/clover/tgsi/compiler.cpp b/src/gallium/state_trackers/clover/tgsi/compiler.cpp
index 9bbd454..f94d19f 100644
--- a/src/gallium/state_trackers/clover/tgsi/compiler.cpp
+++ b/src/gallium/state_trackers/clover/tgsi/compiler.cpp
@@ -76,7 +76,7 @@ namespace {
             }
          }
 
-         m.syms.push_back({ name, 0, offset, args });
+         m.syms.push_back({ name, 0, offset, args, {} });
       }
    }
 
-- 
2.5.5



More information about the mesa-dev mailing list