diff options
Diffstat (limited to 'src/gallium/state_trackers/clover/llvm/invocation.cpp')
-rw-r--r-- | src/gallium/state_trackers/clover/llvm/invocation.cpp | 158 |
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; |