mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 02:28:10 +02:00
clover: implements clGetKernelArgInfo
Reviewed-by: Francisco Jerez <currojerez@riseup.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4974>
This commit is contained in:
parent
d7d66e30f2
commit
9aea6e3374
6 changed files with 154 additions and 12 deletions
|
|
@ -192,9 +192,46 @@ 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 };
|
||||
|
||||
auto info = obj(d_kern).args_infos().at(idx);
|
||||
|
||||
if (info.arg_name.empty())
|
||||
return CL_KERNEL_ARG_INFO_NOT_AVAILABLE;
|
||||
|
||||
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 (std::out_of_range &e) {
|
||||
return CL_INVALID_ARG_INDEX;
|
||||
|
||||
} catch (error &e) {
|
||||
return e.get();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
|||
|
|
@ -153,6 +153,16 @@ kernel::args() const {
|
|||
return map(derefs(), _args);
|
||||
}
|
||||
|
||||
std::vector<clover::module::arg_info>
|
||||
kernel::args_infos() {
|
||||
std::vector<clover::module::arg_info> infos;
|
||||
for (auto &marg: find(name_equals(_name), program().symbols()).args)
|
||||
if (marg.semantic == clover::module::argument::general)
|
||||
infos.emplace_back(marg.info);
|
||||
|
||||
return infos;
|
||||
}
|
||||
|
||||
const module &
|
||||
kernel::module(const command_queue &q) const {
|
||||
return program().build(q.device()).binary;
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ namespace clover {
|
|||
|
||||
argument_range args();
|
||||
const_argument_range args() const;
|
||||
std::vector<clover::module::arg_info> args_infos();
|
||||
|
||||
const intrusive_ref<clover::program> program;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "CL/cl.h"
|
||||
|
||||
namespace clover {
|
||||
struct module {
|
||||
typedef uint32_t resource_id;
|
||||
|
|
@ -53,6 +55,25 @@ namespace clover {
|
|||
std::vector<char> data;
|
||||
};
|
||||
|
||||
struct arg_info {
|
||||
arg_info(const std::string &arg_name, const std::string &type_name,
|
||||
const cl_kernel_arg_type_qualifier type_qualifier,
|
||||
const cl_kernel_arg_address_qualifier address_qualifier,
|
||||
const cl_kernel_arg_access_qualifier access_qualifier) :
|
||||
arg_name(arg_name), type_name(type_name),
|
||||
type_qualifier(type_qualifier),
|
||||
address_qualifier(address_qualifier),
|
||||
access_qualifier(access_qualifier) { };
|
||||
arg_info() : arg_name(""), type_name(""), type_qualifier(0),
|
||||
address_qualifier(0), access_qualifier(0) { };
|
||||
|
||||
std::string arg_name;
|
||||
std::string type_name;
|
||||
cl_kernel_arg_type_qualifier type_qualifier;
|
||||
cl_kernel_arg_address_qualifier address_qualifier;
|
||||
cl_kernel_arg_access_qualifier access_qualifier;
|
||||
};
|
||||
|
||||
struct argument {
|
||||
enum type {
|
||||
scalar,
|
||||
|
|
@ -103,6 +124,7 @@ namespace clover {
|
|||
size_t target_align;
|
||||
ext_type ext_type;
|
||||
semantic semantic;
|
||||
arg_info info;
|
||||
};
|
||||
|
||||
struct symbol {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,43 @@ namespace {
|
|||
unreachable("Unknown image type");
|
||||
}
|
||||
|
||||
module::arg_info create_arg_info(const std::string &arg_name,
|
||||
const std::string &type_name,
|
||||
const std::string &type_qualifier,
|
||||
const int address_qualifier,
|
||||
const std::string &access_qualifier) {
|
||||
|
||||
cl_kernel_arg_type_qualifier cl_type_qualifier =
|
||||
CL_KERNEL_ARG_TYPE_NONE;
|
||||
if (type_qualifier.find("const") != std::string::npos)
|
||||
cl_type_qualifier |= CL_KERNEL_ARG_TYPE_CONST;
|
||||
if (type_qualifier.find("restrict") != std::string::npos)
|
||||
cl_type_qualifier |= CL_KERNEL_ARG_TYPE_RESTRICT;
|
||||
if (type_qualifier.find("volatile") != std::string::npos)
|
||||
cl_type_qualifier |= CL_KERNEL_ARG_TYPE_VOLATILE;
|
||||
|
||||
cl_kernel_arg_address_qualifier cl_address_qualifier =
|
||||
CL_KERNEL_ARG_ADDRESS_PRIVATE;
|
||||
if (address_qualifier == 1)
|
||||
cl_address_qualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL;
|
||||
else if (address_qualifier == 2)
|
||||
cl_address_qualifier = CL_KERNEL_ARG_ADDRESS_CONSTANT;
|
||||
else if (address_qualifier == 3)
|
||||
cl_address_qualifier = CL_KERNEL_ARG_ADDRESS_LOCAL;
|
||||
|
||||
cl_kernel_arg_access_qualifier cl_access_qualifier =
|
||||
CL_KERNEL_ARG_ACCESS_NONE;
|
||||
if (access_qualifier == "read_only")
|
||||
cl_access_qualifier = CL_KERNEL_ARG_ACCESS_READ_ONLY;
|
||||
else if (access_qualifier == "write_only")
|
||||
cl_access_qualifier = CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
|
||||
else if (access_qualifier == "read_write")
|
||||
cl_access_qualifier = CL_KERNEL_ARG_ACCESS_READ_WRITE;
|
||||
|
||||
return module::arg_info(arg_name, type_name, cl_type_qualifier,
|
||||
cl_address_qualifier, cl_access_qualifier);
|
||||
}
|
||||
|
||||
std::vector<module::argument>
|
||||
make_kernel_args(const Module &mod, const std::string &kernel_name,
|
||||
const clang::CompilerInstance &c) {
|
||||
|
|
@ -87,12 +124,11 @@ namespace {
|
|||
const unsigned target_size = dl.getTypeStoreSize(arg_type);
|
||||
const unsigned target_align = dl.getABITypeAlignment(arg_type);
|
||||
|
||||
const auto type_name = get_argument_metadata(f, arg,
|
||||
"kernel_arg_type");
|
||||
|
||||
const auto type_name = get_str_argument_metadata(f, arg,
|
||||
"kernel_arg_type");
|
||||
if (type_name == "image2d_t" || type_name == "image3d_t") {
|
||||
// Image.
|
||||
const auto access_qual = get_argument_metadata(
|
||||
const auto access_qual = get_str_argument_metadata(
|
||||
f, arg, "kernel_arg_access_qual");
|
||||
args.emplace_back(get_image_type(type_name, access_qual),
|
||||
target_size, target_size,
|
||||
|
|
@ -153,6 +189,16 @@ namespace {
|
|||
(needs_sign_ext ? module::argument::sign_ext :
|
||||
module::argument::zero_ext));
|
||||
}
|
||||
|
||||
// Add kernel argument infos if built with -cl-kernel-arg-info.
|
||||
if (c.getCodeGenOpts().EmitOpenCLArgMetadata) {
|
||||
args.back().info = create_arg_info(
|
||||
get_str_argument_metadata(f, arg, "kernel_arg_name"),
|
||||
type_name,
|
||||
get_str_argument_metadata(f, arg, "kernel_arg_type_qual"),
|
||||
get_uint_argument_metadata(f, arg, "kernel_arg_addr_space"),
|
||||
get_str_argument_metadata(f, arg, "kernel_arg_access_qual"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,10 @@ namespace clover {
|
|||
get_kernel_metadata_operands(const ::llvm::Function &f,
|
||||
const std::string &name) {
|
||||
const auto data_node = f.getMetadata(name);
|
||||
return range(data_node->op_begin(), data_node->op_end());
|
||||
if (data_node)
|
||||
return range(data_node->op_begin(), data_node->op_end());
|
||||
else
|
||||
return iterator_range< ::llvm::MDNode::op_iterator>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -57,12 +60,35 @@ namespace clover {
|
|||
/// argument given by \p arg.
|
||||
///
|
||||
inline std::string
|
||||
get_argument_metadata(const ::llvm::Function &f,
|
||||
get_str_argument_metadata(const ::llvm::Function &f,
|
||||
const ::llvm::Argument &arg,
|
||||
const std::string &name) {
|
||||
return ::llvm::cast< ::llvm::MDString>(
|
||||
detail::get_kernel_metadata_operands(f, name)[arg.getArgNo()])
|
||||
->getString().str();
|
||||
auto operands = detail::get_kernel_metadata_operands(f, name);
|
||||
if (operands.size() > arg.getArgNo()) {
|
||||
return ::llvm::cast< ::llvm::MDString>(operands[arg.getArgNo()])
|
||||
->getString().str();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Extract the int metadata node \p name corresponding to the kernel
|
||||
/// argument given by \p arg.
|
||||
///
|
||||
inline uint
|
||||
get_uint_argument_metadata(const ::llvm::Function &f,
|
||||
const ::llvm::Argument &arg,
|
||||
const std::string &name) {
|
||||
auto operands = detail::get_kernel_metadata_operands(f, name);
|
||||
if (operands.size() >= arg.getArgNo()) {
|
||||
auto meta_arg_value = ::llvm::cast< ::llvm::ConstantAsMetadata>(
|
||||
operands[arg.getArgNo()])->getValue();
|
||||
return ::llvm::cast< ::llvm::ConstantInt>(meta_arg_value)
|
||||
->getLimitedValue(UINT_MAX);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue