[Mesa-dev] [PATCH 5/7] clover: seperate build and compile
EdB
edb+mesa at sigluy.net
Sun Dec 14 02:31:25 PST 2014
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
More information about the mesa-dev
mailing list