clover: Add support for compiler flags
authorTom Stellard <thomas.stellard@amd.com>
Tue, 27 Nov 2012 21:57:15 +0000 (21:57 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 13 Dec 2012 19:22:44 +0000 (19:22 +0000)
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
src/gallium/state_trackers/clover/api/program.cpp
src/gallium/state_trackers/clover/core/compiler.hpp
src/gallium/state_trackers/clover/core/program.cpp
src/gallium/state_trackers/clover/core/program.hpp
src/gallium/state_trackers/clover/llvm/invocation.cpp

index 74de840d3df68c6407a75dd1a4baaa3ad6a87a20..06f96f1845c656a938a0c0ea5ecf6968e809020a 100644 (file)
@@ -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;
index a43050a22a3e4e620a1c82ff46163172f5b97eeb..386950737092acb7f163d3f45b0c0ba641517c63 100644 (file)
@@ -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);
 }
index 5fcda23fc659341cda5c3087259351740d700337..92f1d6f5aa55d1963aedc904b6073c0c1f59b924 100644 (file)
@@ -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
index f3858f6ce98ed8081cb8fff5b46b2162c6584c5f..0cda8eeceb37c0e04ebb8d3504f6f247506e2903 100644 (file)
@@ -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;
 };
 
index 2b07053ba208582f302772f6d0715ea2437abe18..c9973679a4c20d641441a341314b3c3e19278e84 100644 (file)
@@ -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);