From 132b6ccd4f81eac3cad5bef42325319708498240 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 17 May 2016 16:03:04 +0200 Subject: [PATCH] clover/llvm: Split compilation and linking. Split the work previously done by compile_program_llvm() into compile_program() (which simply runs the front-end and serializes the resulting LLVM IR) and link_program() (which takes care of everything else down to binary codegen). [ Serge Martin: allow LLVM IR dump after compilation ] Reviewed-by: Serge Martin Tested-by: Jan Vesely --- .../state_trackers/clover/Makefile.sources | 1 + .../state_trackers/clover/llvm/invocation.cpp | 58 ++++++++++++++----- .../state_trackers/clover/llvm/invocation.hpp | 47 +++++++++++++++ 3 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 src/gallium/state_trackers/clover/llvm/invocation.hpp diff --git a/src/gallium/state_trackers/clover/Makefile.sources b/src/gallium/state_trackers/clover/Makefile.sources index 0d1fb8cb018..bbfb2de6245 100644 --- a/src/gallium/state_trackers/clover/Makefile.sources +++ b/src/gallium/state_trackers/clover/Makefile.sources @@ -60,6 +60,7 @@ LLVM_SOURCES := \ llvm/codegen.hpp \ llvm/compat.hpp \ llvm/invocation.cpp \ + llvm/invocation.hpp \ llvm/metadata.hpp \ llvm/util.hpp diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp index 23971bb9f9e..3bb7d72a4f4 100644 --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp @@ -26,9 +26,9 @@ #include "llvm/codegen.hpp" #include "llvm/compat.hpp" +#include "llvm/invocation.hpp" #include "llvm/metadata.hpp" #include "llvm/util.hpp" -#include "core/compiler.hpp" #include "util/algorithm.hpp" #include @@ -177,7 +177,30 @@ namespace { return act.takeModule(); } +} + +module +clover::llvm::compile_program(const std::string &source, + const header_map &headers, + const std::string &target, + const std::string &opts, + std::string &r_log) { + if (has_flag(debug::clc)) + debug::log(".cl", "// Options: " + opts + '\n' + source); + auto ctx = create_context(r_log); + auto c = create_compiler_instance(target, tokenize(opts + " input.cl"), + r_log); + auto mod = compile(*ctx, *c, "input.cl", source, headers, target, opts, + r_log); + + if (has_flag(debug::llvm)) + debug::log(".ll", print_module_bitcode(*mod)); + + return build_module_library(*mod); +} + +namespace { void optimize(Module &mod, unsigned optimization_level) { compat::pass_manager pm; @@ -209,21 +232,15 @@ namespace { } module -clover::compile_program_llvm(const std::string &source, - const header_map &headers, - enum pipe_shader_ir ir, - const std::string &target, - const std::string &opts, - std::string &r_log) { - if (has_flag(debug::clc)) - debug::log(".cl", "// Build options: " + opts + '\n' + source); - +clover::llvm::link_program(const std::vector &modules, + enum pipe_shader_ir ir, const std::string &target, + const std::string &opts, std::string &r_log) { + std::vector options = tokenize(opts + " input.cl"); auto ctx = create_context(r_log); - // The input file name must have the .cl extension in order for the - // CompilerInvocation class to recognize it as an OpenCL source file. - const auto c = create_compiler_instance(target, tokenize(opts + " input.cl"), - r_log); - auto mod = compile(*ctx, *c, "input.cl", source, headers, target, opts, r_log); + auto c = create_compiler_instance(target, options, r_log); + // XXX - Implement linkage of multiple clover modules. + assert(modules.size() == 1); + auto mod = parse_module_library(modules[0], *ctx, r_log); optimize(*mod, c->getCodeGenOpts().OptimizationLevel); @@ -252,3 +269,14 @@ clover::compile_program_llvm(const std::string &source, return m; } + +module +clover::compile_program_llvm(const std::string &source, + const header_map &headers, + enum pipe_shader_ir ir, + const std::string &target, + const std::string &opts, + std::string &r_log) { + const auto mod = compile_program(source, headers, target, opts, r_log); + return link_program({ mod }, ir, target, opts, r_log); +} diff --git a/src/gallium/state_trackers/clover/llvm/invocation.hpp b/src/gallium/state_trackers/clover/llvm/invocation.hpp new file mode 100644 index 00000000000..9e90c509f25 --- /dev/null +++ b/src/gallium/state_trackers/clover/llvm/invocation.hpp @@ -0,0 +1,47 @@ +// +// Copyright 2016 Francisco Jerez +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#ifndef CLOVER_LLVM_INVOCATION_HPP +#define CLOVER_LLVM_INVOCATION_HPP + +#include "core/compiler.hpp" +#include "core/error.hpp" +#include "core/module.hpp" +#include "pipe/p_defines.h" + +namespace clover { + namespace llvm { + module compile_program(const std::string &source, + const header_map &headers, + const std::string &target, + const std::string &opts, + std::string &r_log); + + module link_program(const std::vector &modules, + enum pipe_shader_ir ir, + const std::string &target, + const std::string &opts, + std::string &r_log); + } +} + +#endif -- 2.30.2