they shouldn't produce the same output --- src/gallium/state_trackers/clover/api/program.cpp | 2 +- .../state_trackers/clover/core/compiler.hpp | 9 +++- src/gallium/state_trackers/clover/core/program.cpp | 46 +++++++++++++--- src/gallium/state_trackers/clover/core/program.hpp | 5 +- .../state_trackers/clover/llvm/invocation.cpp | 61 ++++++++++++++++++++-- .../state_trackers/clover/tgsi/compiler.cpp | 2 +- 6 files changed, 110 insertions(+), 15 deletions(-)
diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp index e9b1f38..204d047 100644 --- a/src/gallium/state_trackers/clover/api/program.cpp +++ b/src/gallium/state_trackers/clover/api/program.cpp @@ -224,7 +224,7 @@ clCompileProgram(cl_program d_prog, cl_uint num_devs, range(header_names, num_headers), objs<allow_empty_tag>(d_header_progs, num_headers)); - prog.build(devs, opts, headers); + prog.compile(devs, opts, headers); return CL_SUCCESS; } catch (error &e) { diff --git a/src/gallium/state_trackers/clover/core/compiler.hpp b/src/gallium/state_trackers/clover/core/compiler.hpp index c68aa39..9072ae3 100644 --- a/src/gallium/state_trackers/clover/core/compiler.hpp +++ b/src/gallium/state_trackers/clover/core/compiler.hpp @@ -30,14 +30,19 @@ namespace clover { typedef std::vector<std::pair<std::string, std::string> > header_map; + module build_program_llvm(const std::string &source, + pipe_shader_ir ir, + const std::string &target, + const std::string &opts, + std::string &r_log); + module compile_program_llvm(const std::string &source, const header_map &headers, - pipe_shader_ir ir, const std::string &target, const std::string &opts, std::string &r_log); - module compile_program_tgsi(const std::string &source); + module build_program_tgsi(const std::string &source); } #endif diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp index 0d6cc40..f4bc6a9 100644 --- a/src/gallium/state_trackers/clover/core/program.cpp +++ b/src/gallium/state_trackers/clover/core/program.cpp @@ -40,15 +40,12 @@ program::program(clover::context &ctx, } void -program::build(const ref_vector<device> &devs, const char *opts, - const header_map &headers) { +program::build(const ref_vector<device> &devs, const char *opts) { if (has_source) { _devices = devs; for (auto &dev : devs) { - _binaries.erase(&dev); - _logs.erase(&dev); - _opts.erase(&dev); + clean(&dev); _opts.insert({ &dev, opts }); @@ -56,8 +53,8 @@ program::build(const ref_vector<device> &devs, const char *opts, try { auto module = (dev.ir_format() == PIPE_SHADER_IR_TGSI ? - compile_program_tgsi(_source) : - compile_program_llvm(_source, headers, + build_program_tgsi(_source) : + build_program_llvm(_source, dev.ir_format(), dev.ir_target(), build_opts(dev), log)); @@ -71,6 +68,41 @@ program::build(const ref_vector<device> &devs, const char *opts, } } +void +program::compile(const ref_vector<device> &devs, const char *opts, + const header_map &headers) { + if (has_source) { + _devices = devs; + + for (auto &dev : devs) { + clean(&dev); + + _opts.insert({ &dev, opts }); + + std::string log; + + try { + auto module = compile_program_llvm(_source, headers, + dev.ir_target(), build_opts(dev), + log); + _binaries.insert({ &dev, module }); + _logs.insert({ &dev, log }); + } catch (const build_error &) { + _logs.insert({ &dev, log }); + throw; + } + } + } +} + + +void +program::clean(const device *dev) { + _binaries.erase(dev); + _logs.erase(dev); + _opts.erase(dev);; +} + const std::string & program::source() const { return _source; diff --git a/src/gallium/state_trackers/clover/core/program.hpp b/src/gallium/state_trackers/clover/core/program.hpp index 183145e..b8a06aa 100644 --- a/src/gallium/state_trackers/clover/core/program.hpp +++ b/src/gallium/state_trackers/clover/core/program.hpp @@ -47,7 +47,8 @@ namespace clover { program & operator=(const program &prog) = delete; - void build(const ref_vector<device> &devs, const char *opts, + void build(const ref_vector<device> &devs, const char *opts); + void compile(const ref_vector<device> &devs, const char *opts, const header_map &headers = {}); const bool has_source; @@ -69,6 +70,8 @@ namespace clover { friend class kernel; private: + void clean(const device *dev); + std::vector<intrusive_ref<device>> _devices; std::map<const device *, module> _binaries; std::map<const device *, std::string> _logs; diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp index 9b91fee..b1d7c71 100644 --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp @@ -688,8 +688,7 @@ namespace { } // End anonymous namespace module -clover::compile_program_llvm(const std::string &source, - const header_map &headers, +clover::build_program_llvm(const std::string &source, enum pipe_shader_ir ir, const std::string &target, const std::string &opts, @@ -713,7 +712,7 @@ clover::compile_program_llvm(const std::string &source, // The input file name must have the .cl extension in order for the // CompilerInvocation class to recognize it as an OpenCL source file. - llvm::Module *mod = compile_llvm(llvm_ctx, source, headers, "input.cl", + llvm::Module *mod = compile_llvm(llvm_ctx, source, {}, "input.cl", triple, processor, opts, address_spaces, optimization_level, r_log); @@ -755,3 +754,59 @@ clover::compile_program_llvm(const std::string &source, return m; } + +module +clover::compile_program_llvm(const std::string &source, + const header_map &headers, + const std::string &target, + const std::string &opts, + std::string &r_log) { + + init_targets(); + + 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, + target.size() - processor_str_len - 1); + clang::LangAS::Map address_spaces; + llvm::LLVMContext llvm_ctx; + unsigned optimization_level; + + llvm_ctx.setDiagnosticHandler(diagnostic_handler, &r_log); + + if (get_debug_flags() & DBG_CLC) + debug_log("// Build options: " + opts + '\n' + source, ".cl"); + + // The input file name must have the .cl extension in order for the + // CompilerInvocation class to recognize it as an OpenCL source file. + llvm::Module *mod = compile_llvm(llvm_ctx, source, headers, "input.cl", + triple, processor, opts, address_spaces, + optimization_level, r_log); + + if (get_debug_flags() & DBG_LLVM) { + std::string log; + llvm::raw_string_ostream s_log(log); + mod->print(s_log, NULL); + s_log.flush(); + debug_log(log, ".ll"); + } + + //serialize for later use + module m; + llvm::SmallVector<char, 1024> llvm_bitcode; + llvm::raw_svector_ostream bitcode_ostream(llvm_bitcode); + llvm::BitstreamWriter writer(llvm_bitcode); + llvm::WriteBitcodeToFile(mod, bitcode_ostream); + bitcode_ostream.flush(); + + std::vector<char> data(llvm_bitcode.begin(), llvm_bitcode.end()); + m.secs.push_back(module::section(0, module::section::text, + data.size(), data)); + +#if HAVE_LLVM >= 0x0306 + // LLVM 3.6 and newer, the user takes ownership of the module. + delete mod; +#endif + + return m; +} diff --git a/src/gallium/state_trackers/clover/tgsi/compiler.cpp b/src/gallium/state_trackers/clover/tgsi/compiler.cpp index b70104e..3bac863 100644 --- a/src/gallium/state_trackers/clover/tgsi/compiler.cpp +++ b/src/gallium/state_trackers/clover/tgsi/compiler.cpp @@ -89,7 +89,7 @@ namespace { } module -clover::compile_program_tgsi(const std::string &source) { +clover::build_program_tgsi(const std::string &source) { const size_t body_pos = source.find("COMP\n"); const char *body = &source[body_pos]; module m; -- 2.4.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev