summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/clover/llvm/invocation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/clover/llvm/invocation.cpp')
-rw-r--r--src/gallium/state_trackers/clover/llvm/invocation.cpp158
1 files changed, 1 insertions, 157 deletions
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index a51411d..857ae2a 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -24,6 +24,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
+#include "llvm/codegen.hpp"
#include "llvm/compat.hpp"
#include "llvm/metadata.hpp"
#include "llvm/util.hpp"
@@ -249,163 +250,6 @@ namespace {
pm.run(mod);
}
- enum module::argument::type
- get_image_type(const std::string &type,
- const std::string &qual) {
- if (type == "image2d_t" && qual == "read_only")
- return module::argument::image2d_rd;
- else if (type == "image2d_t" && qual == "write_only")
- return module::argument::image2d_wr;
- else if (type == "image3d_t" && qual == "read_only")
- return module::argument::image3d_rd;
- else if (type == "image3d_t" && qual == "write_only")
- return module::argument::image3d_wr;
- else
- unreachable("Unknown image type");
- }
-
- std::vector<module::argument>
- make_kernel_args(const Module &mod, const std::string &kernel_name,
- const clang::CompilerInstance &c) {
- std::vector<module::argument> args;
- const auto address_spaces = c.getTarget().getAddressSpaceMap();
- const Function &f = *mod.getFunction(kernel_name);
- ::llvm::DataLayout dl(&mod);
- const auto size_type =
- dl.getSmallestLegalIntType(mod.getContext(), sizeof(cl_uint) * 8);
-
- for (const auto &arg : f.args()) {
- const auto arg_type = arg.getType();
-
- // OpenCL 1.2 specification, Ch. 6.1.5: "A built-in data
- // type that is not a power of two bytes in size must be
- // aligned to the next larger power of two". We need this
- // alignment for three element vectors, which have
- // non-power-of-2 store size.
- const unsigned arg_store_size = dl.getTypeStoreSize(arg_type);
- const unsigned arg_api_size = util_next_power_of_two(arg_store_size);
-
- const auto target_type = !arg_type->isIntegerTy() ? arg_type :
- dl.getSmallestLegalIntType(mod.getContext(), arg_store_size * 8);
- const unsigned target_size = dl.getTypeStoreSize(target_type);
- const unsigned target_align = dl.getABITypeAlignment(target_type);
-
- const auto type_name = get_argument_metadata(f, arg,
- "kernel_arg_type");
-
- if (type_name == "image2d_t" || type_name == "image3d_t") {
- // Image.
- const auto access_qual = get_argument_metadata(
- f, arg, "kernel_arg_access_qual");
- args.emplace_back(get_image_type(type_name, access_qual),
- arg_store_size, target_size,
- target_align, module::argument::zero_ext);
-
- } else if (type_name == "__llvm_image_size") {
- // Image size implicit argument.
- args.emplace_back(module::argument::scalar, sizeof(cl_uint),
- dl.getTypeStoreSize(size_type),
- dl.getABITypeAlignment(size_type),
- module::argument::zero_ext,
- module::argument::image_size);
-
- } else if (type_name == "__llvm_image_format") {
- // Image format implicit argument.
- args.emplace_back(module::argument::scalar, sizeof(cl_uint),
- dl.getTypeStoreSize(size_type),
- dl.getABITypeAlignment(size_type),
- module::argument::zero_ext,
- module::argument::image_format);
-
- } else {
- // Other types.
- const auto actual_type =
- isa<::llvm::PointerType>(arg_type) && arg.hasByValAttr() ?
- cast<::llvm::PointerType>(arg_type)->getElementType() : arg_type;
-
- if (actual_type->isPointerTy()) {
- const unsigned address_space =
- cast<::llvm::PointerType>(actual_type)->getAddressSpace();
-
- if (address_space == address_spaces[clang::LangAS::opencl_local
- - clang::LangAS::Offset]) {
- args.emplace_back(module::argument::local, arg_api_size,
- target_size, target_align,
- module::argument::zero_ext);
- } else {
- // XXX: Correctly handle constant address space. There is no
- // way for r600g to pass a handle for constant buffers back
- // to clover like it can for global buffers, so
- // creating constant arguments will break r600g. For now,
- // continue treating constant buffers as global buffers
- // until we can come up with a way to create handles for
- // constant buffers.
- args.emplace_back(module::argument::global, arg_api_size,
- target_size, target_align,
- module::argument::zero_ext);
- }
-
- } else {
- const bool needs_sign_ext = f.getAttributes().hasAttribute(
- arg.getArgNo() + 1, ::llvm::Attribute::SExt);
-
- args.emplace_back(module::argument::scalar, arg_api_size,
- target_size, target_align,
- (needs_sign_ext ? module::argument::sign_ext :
- module::argument::zero_ext));
- }
- }
- }
-
- // Append implicit arguments. XXX - The types, ordering and
- // vector size of the implicit arguments should depend on the
- // target according to the selected calling convention.
- args.emplace_back(module::argument::scalar, sizeof(cl_uint),
- dl.getTypeStoreSize(size_type),
- dl.getABITypeAlignment(size_type),
- module::argument::zero_ext,
- module::argument::grid_dimension);
-
- args.emplace_back(module::argument::scalar, sizeof(cl_uint),
- dl.getTypeStoreSize(size_type),
- dl.getABITypeAlignment(size_type),
- module::argument::zero_ext,
- module::argument::grid_offset);
-
- return args;
- }
-
- 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, {} };
-
- text.data.insert(text.data.end(), reinterpret_cast<const char *>(&header),
- reinterpret_cast<const char *>(&header) + sizeof(header));
- text.data.insert(text.data.end(), code.begin(), code.end());
-
- return text;
- }
-
- module
- build_module_common(const Module &mod,
- const std::vector<char> &code,
- const std::map<std::string,
- unsigned> &offsets,
- const clang::CompilerInstance &c) {
- module m;
-
- 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));
- }
-
- m.secs.push_back(make_text_section(code));
- return m;
- }
-
std::map<std::string, unsigned>
get_symbol_offsets(const ::llvm::Module &mod) {
std::map<std::string, unsigned> offsets;