they produce different binaries --- src/gallium/state_trackers/clover/api/program.cpp | 2 +- .../state_trackers/clover/core/compiler.hpp | 12 ++- src/gallium/state_trackers/clover/core/program.cpp | 48 +++++++-- src/gallium/state_trackers/clover/core/program.hpp | 6 +- .../state_trackers/clover/llvm/invocation.cpp | 112 ++++++++++++++++----- .../state_trackers/clover/tgsi/compiler.cpp | 2 +- 6 files changed, 140 insertions(+), 42 deletions(-)
diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp index 60184ed..1e91da1 100644 --- a/src/gallium/state_trackers/clover/api/program.cpp +++ b/src/gallium/state_trackers/clover/api/program.cpp @@ -222,7 +222,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 7210d1e..75c7435 100644 --- a/src/gallium/state_trackers/clover/core/compiler.hpp +++ b/src/gallium/state_trackers/clover/core/compiler.hpp @@ -32,14 +32,20 @@ namespace clover { typedef compat::vector<compat::pair<compat::string, compat::string> > header_map; - module compile_program_llvm(const compat::string &source, - const header_map &headers, + module build_program_llvm(const compat::string &source, pipe_shader_ir ir, const compat::string &target, const compat::string &opts, compat::string &r_log); - module compile_program_tgsi(const compat::string &source); + module compile_program_llvm(const compat::string &source, + const header_map &headers, + pipe_shader_ir ir, + const compat::string &target, + const compat::string &opts, + compat::string &r_log); + + module build_program_tgsi(const compat::string &source); } #endif diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp index 5e05a33..a0aeb46 100644 --- a/src/gallium/state_trackers/clover/core/program.cpp +++ b/src/gallium/state_trackers/clover/core/program.cpp @@ -40,24 +40,19 @@ 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); - - _opts.insert({ &dev, opts }); + reset_device(&dev, opts); compat::string log; 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 +66,32 @@ 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) { + reset_device(&dev, opts); + + compat::string log; + + try { + auto module = compile_program_llvm(_source, headers, + dev.ir_format(), + dev.ir_target(), build_opts(dev), + log); + _binaries.insert({ &dev, module }); + _logs.insert({ &dev, log }); + } catch (const build_error &) { + _logs.insert({ &dev, log }); + throw; + } + } + } +} + bool program::has_executable() const { for (auto &bin : _binaries) { @@ -127,3 +148,12 @@ unsigned program::kernel_ref_count() const { return _kernel_ref_counter.ref_count(); } + +void +program::reset_device(const device *dev, const char *opts) { + _binaries.erase(dev); + _logs.erase(dev); + _opts.erase(dev); + + _opts.insert({ dev, opts }); +} diff --git a/src/gallium/state_trackers/clover/core/program.hpp b/src/gallium/state_trackers/clover/core/program.hpp index 7f61d88..1451c02 100644 --- a/src/gallium/state_trackers/clover/core/program.hpp +++ b/src/gallium/state_trackers/clover/core/program.hpp @@ -47,8 +47,9 @@ namespace clover { program & operator=(const program &prog) = delete; - void build(const ref_vector<device> &devs, const char *opts, - const header_map &headers = {}); + void build(const ref_vector<device> &devs, const char *opts); + void compile(const ref_vector<device> &devs, const char *opts, + const header_map &headers); bool has_executable() const; const bool has_source; @@ -70,6 +71,7 @@ namespace clover { friend class kernel; private: + void reset_device(const device *dev, const char *opts); 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 1eb47f5..390c625 100644 --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp @@ -129,22 +129,7 @@ namespace { } } - llvm::Module * - compile_llvm(llvm::LLVMContext &llvm_ctx, const std::string &source, - const header_map &headers, - const std::string &name, const std::string &triple, - const std::string &processor, const std::string &opts, - clang::LangAS::Map& address_spaces, unsigned &optimization_level, - compat::string &r_log) { - - clang::CompilerInstance c; - clang::EmitLLVMOnlyAction act(&llvm_ctx); - std::string log; - llvm::raw_string_ostream s_log(log); - std::string libclc_path = LIBCLC_LIBEXECDIR + processor + "-" - + triple + ".bc"; - - // Parse the compiler options: + bool parse_args(clang::CompilerInstance &c, const std::string &opts) { std::vector<std::string> opts_array; std::istringstream ss(opts); @@ -154,8 +139,6 @@ namespace { opts_array.push_back(opt); } - opts_array.push_back(name); - std::vector<const char *> opts_carray; for (unsigned i = 0; i < opts_array.size(); i++) { opts_carray.push_back(opts_array.at(i).c_str()); @@ -170,15 +153,32 @@ namespace { DiagsBuffer = new clang::TextDiagnosticBuffer(); clang::DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); - bool Success; - Success = clang::CompilerInvocation::CreateFromArgs(c.getInvocation(), + return clang::CompilerInvocation::CreateFromArgs(c.getInvocation(), opts_carray.data(), opts_carray.data() + opts_carray.size(), Diags); - if (!Success) { + } + + llvm::Module * + compile_llvm(llvm::LLVMContext &llvm_ctx, const std::string &source, + const header_map &headers, + const std::string &name, const std::string &triple, + const std::string &processor, const std::string &opts, + clang::LangAS::Map& address_spaces, unsigned &optimization_level, + compat::string &r_log) { + + clang::CompilerInstance c; + clang::EmitLLVMOnlyAction act(&llvm_ctx); + std::string log; + llvm::raw_string_ostream s_log(log); + std::string libclc_path = LIBCLC_LIBEXECDIR + processor + "-" + + triple + ".bc"; + + std::string options = opts + " " + name; + if (!parse_args(c, options)) throw error(CL_INVALID_COMPILER_OPTIONS); - } + c.getFrontendOpts().ProgramAction = clang::frontend::EmitLLVMOnly; c.getHeaderSearchOpts().UseBuiltinIncludes = true; c.getHeaderSearchOpts().UseStandardSystemIncludes = true; @@ -686,8 +686,7 @@ namespace { } // End anonymous namespace module -clover::compile_program_llvm(const compat::string &source, - const header_map &headers, +clover::build_program_llvm(const compat::string &source, enum pipe_shader_ir ir, const compat::string &target, const compat::string &opts, @@ -714,7 +713,7 @@ clover::compile_program_llvm(const compat::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, header_map(), "input.cl", triple, processor, opts, address_spaces, optimization_level, r_log); @@ -743,7 +742,7 @@ clover::compile_program_llvm(const compat::string &source, break; case PIPE_SHADER_IR_NATIVE: { std::vector<char> code = compile_native(mod, triple, processor, - debug_flags & DBG_ASM, r_log); + debug_flags & DBG_ASM, r_log); m = build_module_native(code, mod, kernels, address_spaces, r_log); break; } @@ -755,3 +754,64 @@ clover::compile_program_llvm(const compat::string &source, return m; } + +module +clover::compile_program_llvm(const compat::string &source, + const header_map &headers, + enum pipe_shader_ir ir, + const compat::string &target, + const compat::string &opts, + compat::string &r_log) { + + unsigned debug_flags = get_debug_flags(); + + std::vector<llvm::Function *> kernels; + size_t processor_str_len = std::string(target.begin()).find_first_of("-"); + std::string processor(target.begin(), 0, processor_str_len); + std::string triple(target.begin(), processor_str_len + 1, + target.size() - processor_str_len - 1); + clang::LangAS::Map address_spaces; + llvm::LLVMContext llvm_ctx; + unsigned optimization_level; + +#if HAVE_LLVM >= 0x0305 + llvm_ctx.setDiagnosticHandler(diagnostic_handler, &r_log); +#endif + + if (debug_flags & DBG_CLC) + debug_log(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, "compile_program.cl", + triple, processor, opts, address_spaces, + optimization_level, r_log); + + + if (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::string data(llvm_bitcode.begin(), llvm_bitcode.end()); + m.secs.push_back(module::section(0, module::section::text_compiled, + 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 d901d2b..51544ae 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 compat::string &source) { +clover::build_program_tgsi(const compat::string &source) { const char *body = source.find("COMP\n"); module m; -- 2.2.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev