summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/clover
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2016-06-03 15:46:21 -0700
committerFrancisco Jerez <[email protected]>2016-07-11 20:34:34 -0700
commitfb3eeb1314c3269818e58e64b460d045ea5b466d (patch)
treea6ee389591b60f7cda3462f2d84acc9d8202c14f /src/gallium/state_trackers/clover
parent9de3f4a59f2f588368a5994a9fe49d4136393852 (diff)
clover/llvm: Implement the -create-library linker option.
[ Serge Martin: disable internalize pass when building a library. Otherwise some functions may be inlined and removed ] Reviewed-by: Serge Martin <[email protected]> Tested-by: Jan Vesely <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/clover')
-rw-r--r--src/gallium/state_trackers/clover/llvm/invocation.cpp47
-rw-r--r--src/gallium/state_trackers/clover/util/functional.hpp21
2 files changed, 44 insertions, 24 deletions
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index 6560b89d1f5..40b00b7ef13 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -202,7 +202,8 @@ clover::llvm::compile_program(const std::string &source,
namespace {
void
- optimize(Module &mod, unsigned optimization_level) {
+ optimize(Module &mod, unsigned optimization_level,
+ bool internalize_symbols) {
compat::pass_manager pm;
compat::add_data_layout_pass(pm);
@@ -219,8 +220,9 @@ namespace {
// list of kernel functions to the internalizer. The internalizer will
// treat the functions in the list as "main" functions and internalize
// all of the other functions.
- compat::add_internalize_pass(pm, map(std::mem_fn(&Function::getName),
- get_kernels(mod)));
+ if (internalize_symbols)
+ compat::add_internalize_pass(pm, map(std::mem_fn(&Function::getName),
+ get_kernels(mod)));
::llvm::PassManagerBuilder pmb;
pmb.OptLevel = optimization_level;
@@ -251,36 +253,33 @@ clover::llvm::link_program(const std::vector<module> &modules,
enum pipe_shader_ir ir, const std::string &target,
const std::string &opts, std::string &r_log) {
std::vector<std::string> options = tokenize(opts + " input.cl");
+ const bool create_library = count("-create-library", options);
+ erase_if(equals("-create-library"), options);
+
auto ctx = create_context(r_log);
auto c = create_compiler_instance(target, options, r_log);
auto mod = link(*ctx, *c, modules, r_log);
- optimize(*mod, c->getCodeGenOpts().OptimizationLevel);
+ optimize(*mod, c->getCodeGenOpts().OptimizationLevel, !create_library);
if (has_flag(debug::llvm))
debug::log(".ll", print_module_bitcode(*mod));
- module m;
- // Build the clover::module
- switch (ir) {
- case PIPE_SHADER_IR_NIR:
- case PIPE_SHADER_IR_TGSI:
- //XXX: Handle TGSI, NIR
- assert(0);
- m = module();
- break;
- case PIPE_SHADER_IR_LLVM:
- m = build_module_bitcode(*mod, *c);
- break;
- case PIPE_SHADER_IR_NATIVE:
- if (has_flag(debug::native))
- debug::log(".asm", print_module_native(*mod, target));
-
- m = build_module_native(*mod, target, *c, r_log);
- break;
- }
+ if (create_library) {
+ return build_module_library(*mod);
+
+ } else if (ir == PIPE_SHADER_IR_LLVM) {
+ return build_module_bitcode(*mod, *c);
- return m;
+ } else if (ir == PIPE_SHADER_IR_NATIVE) {
+ if (has_flag(debug::native))
+ debug::log(".asm", print_module_native(*mod, target));
+
+ return build_module_native(*mod, target, *c, r_log);
+
+ } else {
+ unreachable("Unsupported IR.");
+ }
}
module
diff --git a/src/gallium/state_trackers/clover/util/functional.hpp b/src/gallium/state_trackers/clover/util/functional.hpp
index ed69155c45b..98bbdff4bd1 100644
--- a/src/gallium/state_trackers/clover/util/functional.hpp
+++ b/src/gallium/state_trackers/clover/util/functional.hpp
@@ -311,6 +311,27 @@ namespace clover {
}
};
+ template<typename T>
+ class equals_t {
+ public:
+ equals_t(T &&x) : x(x) {}
+
+ template<typename S>
+ bool
+ operator()(S &&y) const {
+ return x == y;
+ }
+
+ private:
+ T x;
+ };
+
+ template<typename T>
+ equals_t<T>
+ equals(T &&x) {
+ return { std::forward<T>(x) };
+ }
+
class name_equals {
public:
name_equals(const std::string &name) : name(name) {