--- .../state_trackers/clover/llvm/invocation.cpp | 87 ++++++++++++---------- .../state_trackers/clover/llvm/ir_compiler.cpp | 46 +++++++++--- .../state_trackers/clover/llvm/ir_compiler.hpp | 4 +- 3 files changed, 85 insertions(+), 52 deletions(-)
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp index be00b65..5b3dd1f 100644 --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp @@ -381,6 +381,24 @@ namespace { } module + serialize_to_clover_module(llvm::Module *mod) { + llvm::SmallVector<char, 1024> llvm_bitcode; + llvm::raw_svector_ostream bitcode_ostream(llvm_bitcode); + llvm::BitstreamWriter writer(llvm_bitcode); + llvm::WriteBitcodeToFile(mod, bitcode_ostream); +#if HAVE_LLVM < 0x0308 + bitcode_ostream.flush(); +#endif + + module m; + std::vector<char> data(llvm_bitcode.begin(), llvm_bitcode.end()); + m.secs.push_back(module::section(0, module::section::text, + data.size(), data)); + + return m; + } + + module build_module_llvm(llvm::Module *mod, clang::LangAS::Map& address_spaces) { @@ -666,7 +684,7 @@ clover::compile_program_llvm(const std::string &source, throw; } - c.optimize(); + c.optimize(false); r_log = c.get_log(); @@ -681,20 +699,7 @@ clover::compile_program_llvm(const std::string &source, } //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); -#if HAVE_LLVM < 0x0308 - bitcode_ostream.flush(); -#endif - - std::vector<char> data(llvm_bitcode.begin(), llvm_bitcode.end()); - m.secs.push_back(module::section(0, module::section::text, - data.size(), data)); - - return m; + return serialize_to_clover_module(mod); } module @@ -718,7 +723,7 @@ clover::link_program_llvm(const std::vector<module> &modules, throw; } - c.optimize(); + c.optimize(true); r_log = c.get_log(); @@ -732,30 +737,34 @@ clover::link_program_llvm(const std::vector<module> &modules, debug_log(log, ".ll"); } - const clang::TargetInfo &info = c.get_info(); - // Get address spaces map to be able to find kernel argument address space - clang::LangAS::Map address_spaces; - memcpy(address_spaces, info.getAddressSpaceMap(), sizeof(address_spaces)); - module m; - // Build the clover::module - switch (ir) { - case PIPE_SHADER_IR_TGSI: - //XXX: Handle TGSI - assert(0); - m = module(); - break; - case PIPE_SHADER_IR_LLVM: - m = build_module_llvm(mod, address_spaces); - break; - case PIPE_SHADER_IR_NATIVE: { - std::vector<char> code = compile_native(mod, - info.getTargetOpts().Triple, - info.getTargetOpts().CPU, - get_debug_flags() & DBG_ASM, - r_log); - m = build_module_native(code, mod, address_spaces, r_log); - break; + if (c.as_library()) { + m = serialize_to_clover_module(mod); + } else { + const clang::TargetInfo &info = c.get_info(); + // Get address spaces map to be able to find kernel argument address space + clang::LangAS::Map address_spaces; + memcpy(address_spaces, info.getAddressSpaceMap(), sizeof(address_spaces)); + + // Build the clover::module + switch (ir) { + case PIPE_SHADER_IR_TGSI: + //XXX: Handle TGSI + assert(0); + m = module(); + break; + case PIPE_SHADER_IR_LLVM: + m = build_module_llvm(mod, address_spaces); + break; + case PIPE_SHADER_IR_NATIVE: { + std::vector<char> code = compile_native(mod, + info.getTargetOpts().Triple, + info.getTargetOpts().CPU, + get_debug_flags() & DBG_ASM, + r_log); + m = build_module_native(code, mod, address_spaces, r_log); + break; + } } } diff --git a/src/gallium/state_trackers/clover/llvm/ir_compiler.cpp b/src/gallium/state_trackers/clover/llvm/ir_compiler.cpp index 5aa77db..ebc2cb7 100644 --- a/src/gallium/state_trackers/clover/llvm/ir_compiler.cpp +++ b/src/gallium/state_trackers/clover/llvm/ir_compiler.cpp @@ -48,7 +48,7 @@ static const std::string input_name("input.cl"); llvm_ir_compiler::llvm_ir_compiler(llvm::LLVMContext *llvm_ctx) : - _llvm_ctx(llvm_ctx), _module(nullptr), _raw_log(_log) { + _llvm_ctx(llvm_ctx), _module(nullptr), _raw_log(_log), _as_library(false) { }; llvm_ir_compiler::~llvm_ir_compiler() { @@ -70,6 +70,15 @@ llvm_ir_compiler::parse_args(const std::string &target, while (!ss.eof()) { std::string opt; getline(ss, opt, ' '); + + if (opt == "-create-library") { + if (error_kind != CL_INVALID_LINKER_OPTIONS) + throw clover::error(error_kind); + + _as_library = true; + continue; + } + opts_array.push_back(opt); } @@ -239,9 +248,12 @@ llvm_ir_compiler::link(const std::vector<clover::module> &modules) { } void -llvm_ir_compiler::optimize() { +llvm_ir_compiler::optimize(bool allow_internalizer) { assert(_module); + if (_as_library) + allow_internalizer = false; + #if HAVE_LLVM >= 0x0307 llvm::legacy::PassManager PM; #else @@ -262,20 +274,24 @@ llvm_ir_compiler::optimize() { // 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. + // + // This is disable for library std::vector<const char*> export_list; - const llvm::NamedMDNode *kernel_node = - _module->getNamedMetadata("opencl.kernels"); - if (kernel_node) { - export_list.reserve(kernel_node->getNumOperands()); - for (unsigned i = 0; i < kernel_node->getNumOperands(); ++i) { + if (allow_internalizer) { + const llvm::NamedMDNode *kernel_node = + _module->getNamedMetadata("opencl.kernels"); + if (kernel_node) { + export_list.reserve(kernel_node->getNumOperands()); + for (unsigned i = 0; i < kernel_node->getNumOperands(); ++i) { #if HAVE_LLVM >= 0x0306 - llvm::Function *kernel = llvm::mdconst::dyn_extract<llvm::Function>( + llvm::Function *kernel = llvm::mdconst::dyn_extract<llvm::Function>( #else - llvm::Function *kernel = llvm::dyn_cast<llvm::Function>( + llvm::Function *kernel = llvm::dyn_cast<llvm::Function>( #endif - kernel_node->getOperand(i)->getOperand(0)); - export_list.push_back(kernel->getName().data()); + kernel_node->getOperand(i)->getOperand(0)); + export_list.push_back(kernel->getName().data()); + } } } @@ -285,7 +301,8 @@ llvm_ir_compiler::optimize() { PM.add(new llvm::DataLayoutPass()); #endif - PM.add(llvm::createInternalizePass(export_list)); + if (allow_internalizer) + PM.add(llvm::createInternalizePass(export_list)); llvm::PassManagerBuilder PMB; PMB.OptLevel = _ci.getCodeGenOpts().OptimizationLevel; @@ -313,3 +330,8 @@ llvm::Module * llvm_ir_compiler::get_module() const { return _module; } + +bool +llvm_ir_compiler::as_library() const { + return _as_library; +} diff --git a/src/gallium/state_trackers/clover/llvm/ir_compiler.hpp b/src/gallium/state_trackers/clover/llvm/ir_compiler.hpp index b8b9ce3..1564488 100644 --- a/src/gallium/state_trackers/clover/llvm/ir_compiler.hpp +++ b/src/gallium/state_trackers/clover/llvm/ir_compiler.hpp @@ -44,11 +44,12 @@ public: cl_int error_kind); void compile(const std::string &source, const header_map &headers); void link(const std::vector<clover::module> &modules); - void optimize(); + void optimize(bool allow_internalizer); const clang::TargetInfo &get_info() const; std::string get_log() const; llvm::Module *get_module() const; + bool as_library() const; private: llvm::LLVMContext *_llvm_ctx; @@ -58,6 +59,7 @@ private: std::string _log; llvm::raw_string_ostream _raw_log; + bool _as_library; }; #endif -- 2.5.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev