Mesa (master): clover: Link libclc before running any optimizations

Tom Stellard tstellar at kemper.freedesktop.org
Wed Oct 16 17:00:32 UTC 2013


Module: Mesa
Branch: master
Commit: de1de88dfc478db597726d88231c6c0a7f936121
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=de1de88dfc478db597726d88231c6c0a7f936121

Author: Tom Stellard <thomas.stellard at amd.com>
Date:   Mon Sep 16 10:32:59 2013 -0700

clover: Link libclc before running any optimizations

This is required in order for clang to correctly handle the OpenCL C
barrier() builtin which has the following restrictions acording to
the OpenCL 1.1 Specification:

If barrier is inside a conditional statement, then all work-items must
enter the conditional if any work-item enters the conditional statement
and executes the barrier.

If barrier is inside a loop, all work-items must execute the barrier for
each iteration of the loop before any are allowed to continue execution
beyond the barrier.

By linking before otimizations, we can replace calls to barrier() with
calls to a target specific intrinsic which has the noduplicate attribute
This attribute prevents clang from performing optimizations which could
violate the above rules.

This attribute must be applied to the call instruction that invokes
the function, so it is not enough to add this attribute the barrier()
declaration.

As a bonus this will probably speed up compile times since we will no
longer need to run link-time optimizations.

---

 .../state_trackers/clover/llvm/invocation.cpp      |   40 ++++++-------------
 1 files changed, 13 insertions(+), 27 deletions(-)

diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index bdc3aee..f14222b 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -121,6 +121,8 @@ namespace {
       clang::EmitLLVMOnlyAction act(&llvm::getGlobalContext());
       std::string log;
       llvm::raw_string_ostream s_log(log);
+      std::string libclc_path = LIBCLC_LIBEXECDIR + processor + "-"
+                                                  + triple + ".bc";
 
       // Parse the compiler options:
       std::vector<std::string> opts_array;
@@ -202,6 +204,15 @@ namespace {
       c.getPreprocessorOpts().addRemappedFile(name,
                                       llvm::MemoryBuffer::getMemBuffer(source));
 
+      // Setting this attribute tells clang to link this file before
+      // performing any optimizations.  This is required so that
+      // we can replace calls to the OpenCL C barrier() builtin
+      // with calls to target intrinsics that have the noduplicate
+      // attribute.  This attribute will prevent Clang from creating
+      // illegal uses of barrier() (e.g. Moving barrier() inside a conditional
+      // that is no executed by all threads) during its optimizaton passes.
+      c.getCodeGenOpts().LinkBitcodeFile = libclc_path;
+
       // Compile the code
       if (!c.ExecuteAction(act))
          throw build_error(log);
@@ -231,32 +242,10 @@ namespace {
    }
 
    void
-   link(llvm::Module *mod, const std::string &triple,
-        const std::string &processor,
+   internalize_functions(llvm::Module *mod,
         const std::vector<llvm::Function *> &kernels) {
 
       llvm::PassManager PM;
-      llvm::PassManagerBuilder Builder;
-      std::string libclc_path = LIBCLC_LIBEXECDIR + processor + "-"
-                                                  + triple + ".bc";
-      // Link the kernel with libclc
-#if HAVE_LLVM < 0x0303
-      bool isNative;
-      llvm::Linker linker("clover", mod);
-      linker.LinkInFile(llvm::sys::Path(libclc_path), isNative);
-      mod = linker.releaseModule();
-#else
-      std::string err_str;
-      llvm::SMDiagnostic err;
-      llvm::Module *libclc_mod = llvm::ParseIRFile(libclc_path, err,
-                                                   mod->getContext());
-      if (llvm::Linker::LinkModules(mod, libclc_mod,
-                                    llvm::Linker::DestroySource,
-                                    &err_str)) {
-         throw build_error(err_str);
-      }
-#endif
-
       // Add a function internalizer pass.
       //
       // By default, the function internalizer pass will look for a function
@@ -284,9 +273,6 @@ namespace {
       std::vector<const char*> dso_list;
       PM.add(llvm::createInternalizePass(export_list, dso_list));
 #endif
-      // Run link time optimizations
-      Builder.OptLevel = 2;
-      Builder.populateLTOPassManager(PM, false, true);
       PM.run(*mod);
    }
 
@@ -406,7 +392,7 @@ clover::compile_program_llvm(const compat::string &source,
 
    find_kernels(mod, kernels);
 
-   link(mod, triple, processor, kernels);
+   internalize_functions(mod, kernels);
 
    // Build the clover::module
    switch (ir) {




More information about the mesa-commit mailing list