summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Stellard <[email protected]>2012-11-27 21:57:15 +0000
committerTom Stellard <[email protected]>2012-12-13 19:22:44 +0000
commitc68babfc3c7b65dd53697528781bd6b6186f5190 (patch)
tree5c5546488db700d88940510b166986f8d7be1ff2 /src
parent7f71efcf7a8eace124e71ca72c86d4c2bdc8042d (diff)
clover: Add support for compiler flags
Reviewed-by: Francisco Jerez <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/clover/api/program.cpp7
-rw-r--r--src/gallium/state_trackers/clover/core/compiler.hpp12
-rw-r--r--src/gallium/state_trackers/clover/core/program.cpp12
-rw-r--r--src/gallium/state_trackers/clover/core/program.hpp3
-rw-r--r--src/gallium/state_trackers/clover/llvm/invocation.cpp49
5 files changed, 71 insertions, 12 deletions
diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp
index 74de840d3df..06f96f1845c 100644
--- a/src/gallium/state_trackers/clover/api/program.cpp
+++ b/src/gallium/state_trackers/clover/api/program.cpp
@@ -142,15 +142,18 @@ clBuildProgram(cl_program prog, cl_uint count, const cl_device_id *devs,
(!pfn_notify && user_data))
throw error(CL_INVALID_VALUE);
+ if (!opts)
+ opts = "";
+
if (devs) {
if (any_of([&](const cl_device_id dev) {
return !prog->ctx.has_device(dev);
}, devs, devs + count))
throw error(CL_INVALID_DEVICE);
- prog->build({ devs, devs + count });
+ prog->build({ devs, devs + count }, opts);
} else {
- prog->build(prog->ctx.devs);
+ prog->build(prog->ctx.devs, opts);
}
return CL_SUCCESS;
diff --git a/src/gallium/state_trackers/clover/core/compiler.hpp b/src/gallium/state_trackers/clover/core/compiler.hpp
index a43050a22a3..38695073709 100644
--- a/src/gallium/state_trackers/clover/core/compiler.hpp
+++ b/src/gallium/state_trackers/clover/core/compiler.hpp
@@ -44,9 +44,19 @@ namespace clover {
compat::vector<char> log;
};
+ class invalid_option_error {
+ public:
+ invalid_option_error() {
+ }
+
+ virtual ~invalid_option_error() {
+ }
+ };
+
module compile_program_llvm(const compat::string &source,
enum pipe_shader_ir ir,
- const compat::string &target);
+ const compat::string &target,
+ const compat::string &opts);
module compile_program_tgsi(const compat::string &source);
}
diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp
index 5fcda23fc65..92f1d6f5aa5 100644
--- a/src/gallium/state_trackers/clover/core/program.cpp
+++ b/src/gallium/state_trackers/clover/core/program.cpp
@@ -41,21 +41,27 @@ _cl_program::_cl_program(clover::context &ctx,
}
void
-_cl_program::build(const std::vector<clover::device *> &devs) {
+_cl_program::build(const std::vector<clover::device *> &devs,
+ const char *opts) {
for (auto dev : devs) {
__binaries.erase(dev);
__logs.erase(dev);
+ __opts.erase(dev);
+
+ __opts.insert({ dev, opts });
try {
auto module = (dev->ir_format() == PIPE_SHADER_IR_TGSI ?
compile_program_tgsi(__source) :
compile_program_llvm(__source, dev->ir_format(),
- dev->ir_target()));
+ dev->ir_target(), build_opts(dev)));
__binaries.insert({ dev, module });
} catch (build_error &e) {
__logs.insert({ dev, e.what() });
throw error(CL_BUILD_PROGRAM_FAILURE);
+ } catch (invalid_option_error &e) {
+ throw error(CL_INVALID_BUILD_OPTIONS);
}
}
}
@@ -77,7 +83,7 @@ _cl_program::build_status(clover::device *dev) const {
std::string
_cl_program::build_opts(clover::device *dev) const {
- return {};
+ return __opts.count(dev) ? __opts.find(dev)->second : "";
}
std::string
diff --git a/src/gallium/state_trackers/clover/core/program.hpp b/src/gallium/state_trackers/clover/core/program.hpp
index f3858f6ce98..0cda8eeceb3 100644
--- a/src/gallium/state_trackers/clover/core/program.hpp
+++ b/src/gallium/state_trackers/clover/core/program.hpp
@@ -41,7 +41,7 @@ public:
const std::vector<clover::device *> &devs,
const std::vector<clover::module> &binaries);
- void build(const std::vector<clover::device *> &devs);
+ void build(const std::vector<clover::device *> &devs, const char *opts);
const std::string &source() const;
const std::map<clover::device *, clover::module> &binaries() const;
@@ -55,6 +55,7 @@ public:
private:
std::map<clover::device *, clover::module> __binaries;
std::map<clover::device *, std::string> __logs;
+ std::map<clover::device *, std::string> __opts;
std::string __source;
};
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index 2b07053ba20..c9973679a4c 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -23,6 +23,7 @@
#include "core/compiler.hpp"
#include <clang/Frontend/CompilerInstance.h>
+#include <clang/Frontend/TextDiagnosticBuffer.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/CodeGen/CodeGenAction.h>
#include <llvm/Bitcode/BitstreamWriter.h>
@@ -51,6 +52,7 @@
#include <iomanip>
#include <fstream>
#include <cstdio>
+#include <sstream>
using namespace clover;
@@ -98,15 +100,49 @@ namespace {
llvm::Module *
compile(const std::string &source, const std::string &name,
- const std::string &triple) {
+ const std::string &triple, const std::string &opts) {
clang::CompilerInstance c;
+ clang::CompilerInvocation invocation;
clang::EmitLLVMOnlyAction act(&llvm::getGlobalContext());
std::string log;
llvm::raw_string_ostream s_log(log);
- c.getFrontendOpts().Inputs.push_back(
- clang::FrontendInputFile(name, clang::IK_OpenCL));
+ // Parse the compiler options:
+ std::vector<std::string> opts_array;
+ std::istringstream ss(opts);
+
+ while (!ss.eof()) {
+ std::string opt;
+ getline(ss, opt, ' ');
+ 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());
+ }
+
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID;
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts;
+ clang::TextDiagnosticBuffer *DiagsBuffer;
+
+ DiagID = new clang::DiagnosticIDs();
+ DiagOpts = new clang::DiagnosticOptions();
+ DiagsBuffer = new clang::TextDiagnosticBuffer();
+
+ clang::DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
+ bool Success;
+
+ Success = clang::CompilerInvocation::CreateFromArgs(c.getInvocation(),
+ opts_carray.data(),
+ opts_carray.data() + opts_carray.size(),
+ Diags);
+ if (!Success) {
+ throw invalid_option_error();
+ }
c.getFrontendOpts().ProgramAction = clang::frontend::EmitLLVMOnly;
c.getHeaderSearchOpts().UseBuiltinIncludes = true;
c.getHeaderSearchOpts().UseStandardSystemIncludes = true;
@@ -271,11 +307,14 @@ namespace {
module
clover::compile_program_llvm(const compat::string &source,
enum pipe_shader_ir ir,
- const compat::string &triple) {
+ const compat::string &triple,
+ const compat::string &opts) {
std::vector<llvm::Function *> kernels;
- llvm::Module *mod = compile(source, "cl_input", triple);
+ // 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(source, "input.cl", triple, opts);
find_kernels(mod, kernels);