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 <edb+mesa@sigluy.net> Tested-by: Jan Vesely <jan.vesely@rutgers.edu>
This commit is contained in:
@@ -202,7 +202,8 @@ clover::llvm::compile_program(const std::string &source,
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void
|
void
|
||||||
optimize(Module &mod, unsigned optimization_level) {
|
optimize(Module &mod, unsigned optimization_level,
|
||||||
|
bool internalize_symbols) {
|
||||||
compat::pass_manager pm;
|
compat::pass_manager pm;
|
||||||
|
|
||||||
compat::add_data_layout_pass(pm);
|
compat::add_data_layout_pass(pm);
|
||||||
@@ -219,6 +220,7 @@ namespace {
|
|||||||
// list of kernel functions to the internalizer. The internalizer will
|
// list of kernel functions to the internalizer. The internalizer will
|
||||||
// treat the functions in the list as "main" functions and internalize
|
// treat the functions in the list as "main" functions and internalize
|
||||||
// all of the other functions.
|
// all of the other functions.
|
||||||
|
if (internalize_symbols)
|
||||||
compat::add_internalize_pass(pm, map(std::mem_fn(&Function::getName),
|
compat::add_internalize_pass(pm, map(std::mem_fn(&Function::getName),
|
||||||
get_kernels(mod)));
|
get_kernels(mod)));
|
||||||
|
|
||||||
@@ -251,36 +253,33 @@ clover::llvm::link_program(const std::vector<module> &modules,
|
|||||||
enum pipe_shader_ir ir, const std::string &target,
|
enum pipe_shader_ir ir, const std::string &target,
|
||||||
const std::string &opts, std::string &r_log) {
|
const std::string &opts, std::string &r_log) {
|
||||||
std::vector<std::string> options = tokenize(opts + " input.cl");
|
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 ctx = create_context(r_log);
|
||||||
auto c = create_compiler_instance(target, options, r_log);
|
auto c = create_compiler_instance(target, options, r_log);
|
||||||
auto mod = link(*ctx, *c, modules, 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))
|
if (has_flag(debug::llvm))
|
||||||
debug::log(".ll", print_module_bitcode(*mod));
|
debug::log(".ll", print_module_bitcode(*mod));
|
||||||
|
|
||||||
module m;
|
if (create_library) {
|
||||||
// Build the clover::module
|
return build_module_library(*mod);
|
||||||
switch (ir) {
|
|
||||||
case PIPE_SHADER_IR_NIR:
|
} else if (ir == PIPE_SHADER_IR_LLVM) {
|
||||||
case PIPE_SHADER_IR_TGSI:
|
return build_module_bitcode(*mod, *c);
|
||||||
//XXX: Handle TGSI, NIR
|
|
||||||
assert(0);
|
} else if (ir == PIPE_SHADER_IR_NATIVE) {
|
||||||
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))
|
if (has_flag(debug::native))
|
||||||
debug::log(".asm", print_module_native(*mod, target));
|
debug::log(".asm", print_module_native(*mod, target));
|
||||||
|
|
||||||
m = build_module_native(*mod, target, *c, r_log);
|
return build_module_native(*mod, target, *c, r_log);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
} else {
|
||||||
|
unreachable("Unsupported IR.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module
|
module
|
||||||
|
@@ -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 {
|
class name_equals {
|
||||||
public:
|
public:
|
||||||
name_equals(const std::string &name) : name(name) {
|
name_equals(const std::string &name) : name(name) {
|
||||||
|
Reference in New Issue
Block a user