--- .../state_trackers/clover/llvm/invocation.cpp | 71 +++++++++++++--------- 1 file changed, 41 insertions(+), 30 deletions(-)
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp index 4da62b9..28198a5 100644 --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp @@ -127,6 +127,16 @@ namespace { return module::deserialize(cs); } #endif + + struct llvm_kernel { + + llvm_kernel() : fn(NULL), offset(0) { + } + + llvm::Function *fn; + size_t offset; + }; + void debug_log(const std::string &msg, const std::string &suffix) { const char *dbg_file = debug_get_option("CLOVER_DEBUG_FILE", "stderr"); if (!strcmp("stderr", dbg_file)) { @@ -277,7 +287,7 @@ namespace { } void - find_kernels(llvm::Module *mod, std::vector<llvm::Function *> &kernels) { + find_kernels(llvm::Module *mod, std::vector<llvm_kernel> &kernels) { const llvm::NamedMDNode *kernel_node = mod->getNamedMetadata("opencl.kernels"); // This means there are no kernels in the program. The spec does not @@ -288,18 +298,20 @@ namespace { } for (unsigned i = 0; i < kernel_node->getNumOperands(); ++i) { + kernels.resize(i + 1); + llvm_kernel &kernel = kernels[i]; #if HAVE_LLVM >= 0x0306 - kernels.push_back(llvm::mdconst::dyn_extract<llvm::Function>( + kernel.fn = llvm::mdconst::dyn_extract<llvm::Function>( #else - kernels.push_back(llvm::dyn_cast<llvm::Function>( + kernel.fn = llvm::dyn_cast<llvm::Function>( #endif - kernel_node->getOperand(i)->getOperand(0))); + kernel_node->getOperand(i)->getOperand(0)); } } void optimize(llvm::Module *mod, unsigned optimization_level, - const std::vector<llvm::Function *> &kernels) { + const std::vector<llvm_kernel> &kernels) { #if HAVE_LLVM >= 0x0307 llvm::legacy::PassManager PM; @@ -322,10 +334,10 @@ namespace { // treat the functions in the list as "main" functions and internalize // all of the other functions. std::vector<const char*> export_list; - for (std::vector<llvm::Function *>::const_iterator I = kernels.begin(), + for (std::vector<llvm_kernel>::const_iterator I = kernels.begin(), E = kernels.end(); I != E; ++I) { - llvm::Function *kernel = *I; + llvm::Function *kernel = (*I).fn; export_list.push_back(kernel->getName().data()); } #if HAVE_LLVM < 0x0305 @@ -350,11 +362,11 @@ namespace { } compat::vector<module::argument> - get_kernel_args(const llvm::Module *mod, const std::string &kernel_name, + get_kernel_args(const llvm::Module *mod, const llvm_kernel &kernel, const clang::LangAS::Map &address_spaces) { compat::vector<module::argument> args; - llvm::Function *kernel_func = mod->getFunction(kernel_name); + llvm::Function *kernel_func = kernel.fn; #if HAVE_LLVM < 0x0305 llvm::DataLayout TD(kernel_func->getParent()->getDataLayout()); @@ -448,7 +460,7 @@ namespace { module build_module_llvm(llvm::Module *mod, - const std::vector<llvm::Function *> &kernels, + const std::vector<llvm_kernel> &kernels, clang::LangAS::Map& address_spaces) { module m; @@ -461,9 +473,10 @@ namespace { bitcode_ostream.flush(); for (unsigned i = 0; i < kernels.size(); ++i) { - std::string kernel_name = kernels[i]->getName(); + const llvm_kernel &kernel = kernels[i]; compat::vector<module::argument> args = - get_kernel_args(mod, kernel_name, address_spaces); + get_kernel_args(mod, kernel, address_spaces); + std::string kernel_name = kernel.fn->getName().str(); m.syms.push_back(module::symbol(kernel_name, 0, i, args )); } @@ -555,9 +568,9 @@ namespace { return code; } - std::map<std::string, unsigned> - get_kernel_offsets(std::vector<char> &code, - const std::vector<llvm::Function *> &kernels, + void + set_kernel_offsets(std::vector<char> &code, + std::vector<llvm_kernel> &kernels, compat::string &r_log) { // One of the libelf implementations @@ -602,32 +615,29 @@ namespace { GElf_Sym *symbol; GElf_Sym s; - std::map<std::string, unsigned> kernel_offsets; symtab_data = elf_getdata(symtab, symtab_data); // Determine the offsets for each kernel for (int i = 0; (symbol = gelf_getsym(symtab_data, i, &s)); i++) { char *name = elf_strptr(elf, symtab_header.sh_link, symbol->st_name); - for (std::vector<llvm::Function*>::const_iterator it = kernels.begin(), - e = kernels.end(); it != e; ++it) { - llvm::Function *f = *it; - if (f->getName() == std::string(name)) - kernel_offsets[f->getName()] = symbol->st_value; + for (unsigned kern_idx = 0, kern_end = kernels.size(); + kern_idx != kern_end; ++kern_idx) { + llvm_kernel& kernel = kernels[kern_idx]; + if (kernel.fn->getName() == std::string(name)) + kernel.offset = symbol->st_value; } } elf_end(elf); - return kernel_offsets; } module build_module_native(std::vector<char> &code, const llvm::Module *mod, - const std::vector<llvm::Function *> &kernels, + std::vector<llvm_kernel> &kernels, const clang::LangAS::Map &address_spaces, compat::string &r_log) { - std::map<std::string, unsigned> kernel_offsets = - get_kernel_offsets(code, kernels, r_log); + set_kernel_offsets(code, kernels, r_log); // Begin building the clover module module m; @@ -641,11 +651,12 @@ namespace { m.secs.push_back(module::section(0, module::section::text, header.num_bytes, data)); - for (std::map<std::string, unsigned>::iterator i = kernel_offsets.begin(), - e = kernel_offsets.end(); i != e; ++i) { + for (std::vector<llvm_kernel>::const_iterator i = kernels.begin(), + e = kernels.end(); i != e; ++i) { compat::vector<module::argument> args = - get_kernel_args(mod, i->first, address_spaces); - m.syms.push_back(module::symbol(i->first, 0, i->second, args )); + get_kernel_args(mod, *i, address_spaces); + std::string kernel_name = (*i).fn->getName().str(); + m.syms.push_back(module::symbol(kernel_name, 0, (*i).offset, args )); } return m; @@ -712,7 +723,7 @@ clover::compile_program_llvm(const compat::string &source, init_targets(); - std::vector<llvm::Function *> kernels; + std::vector<llvm_kernel> kernels; size_t processor_str_len = std::string(target).find_first_of("-"); std::string processor(target, 0, processor_str_len); std::string triple(target, processor_str_len + 1, -- 2.0.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev