[Mesa-dev] [PATCH] clover: Add a function internalizer pass before LTO

Francisco Jerez currojerez at riseup.net
Thu Jun 28 06:45:37 PDT 2012


Tom Stellard <thomas.stellard at amd.com> writes:

> I'll commit this tomorrow unless there are objections.
>
Looks OK to me, aside from the std::vector's being passed around by
value instead of by const reference.

> -Tom
>
> On Thu, Jun 21, 2012 at 02:05:24PM -0400, Tom Stellard wrote:
>> The function internalizer pass marks non-kernel functions as internal,
>> which enables optimizations like function inlining and global dead-code
>> elimination.
>> ---
>>  .../state_trackers/clover/llvm/invocation.cpp      |   58 ++++++++++++++++----
>>  1 files changed, 48 insertions(+), 10 deletions(-)
>> 
>> diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
>> index 27276bc..2d155d5 100644
>> --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
>> +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
>> @@ -36,6 +36,7 @@
>>  #include <llvm/Support/MemoryBuffer.h>
>>  #include <llvm/Support/PathV1.h>
>>  #include <llvm/Target/TargetData.h>
>> +#include <llvm/Transforms/IPO.h>
>>  #include <llvm/Transforms/IPO/PassManagerBuilder.h>
>>  
>>  #include "pipe/p_state.h"
>> @@ -134,7 +135,18 @@ namespace {
>>     }
>>  
>>     void
>> -   link(llvm::Module *mod, const std::string &triple) {
>> +   find_kernels(llvm::Module *mod, std::vector<llvm::Function *> &kernels) {
>> +      const llvm::NamedMDNode *kernel_node =
>> +                                 mod->getNamedMetadata("opencl.kernels");
>> +      for (unsigned i = 0; i < kernel_node->getNumOperands(); ++i) {
>> +         kernels.push_back(llvm::dyn_cast<llvm::Function>(
>> +                                    kernel_node->getOperand(i)->getOperand(0)));
>> +      }
>> +   }
>> +
>> +   void
>> +   link(llvm::Module *mod, const std::string &triple,
>> +        std::vector<llvm::Function *> kernels) {
>>  
>>        llvm::PassManager PM;
>>        llvm::PassManagerBuilder Builder;
>> @@ -145,14 +157,37 @@ namespace {
>>        linker.LinkInFile(llvm::sys::Path(LIBCLC_PATH + triple + "/lib/builtins.bc"), isNative);
>>        mod = linker.releaseModule();
>>  
>> +      // Add a function internalizer pass.
>> +      //
>> +      // By default, the function internalizer pass will look for a function
>> +      // called "main" and then mark all other functions as internal.  Marking
>> +      // functions as internal enables the optimizer to perform optimizations
>> +      // like function inlining and global dead-code elimination.
>> +      //
>> +      // When there is no "main" function in a module, the internalize pass will
>> +      // treat the module like a library, and it won't internalize any functions.
>> +      // Since there is no "main" function in our kernels, we need to tell
>> +      // the internalizer pass that this module is not a library by passing a
>> +      // 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.
>> +      std::vector<const char*> export_list;
>> +      for (std::vector<llvm::Function *>::iterator I = kernels.begin(),
>> +                                                   E = kernels.end();
>> +                                                   I != E; ++I) {
>> +         llvm::Function *kernel = *I;
>> +         export_list.push_back(kernel->getName().data());
>> +      }
>> +      PM.add(llvm::createInternalizePass(export_list));
>> +
>>        // Run link time optimizations
>> -      Builder.populateLTOPassManager(PM, false, true);
>>        Builder.OptLevel = 2;
>> +      Builder.populateLTOPassManager(PM, false, true);
>>        PM.run(*mod);
>>     }
>>  
>>     module
>> -   build_module_llvm(llvm::Module *mod) {
>> +   build_module_llvm(llvm::Module *mod, std::vector<llvm::Function *> kernels) {
>>  
>>        module m;
>>        struct pipe_llvm_program_header header;
>> @@ -163,15 +198,14 @@ namespace {
>>        llvm::WriteBitcodeToFile(mod, bitcode_ostream);
>>        bitcode_ostream.flush();
>>  
>> +      llvm::Function * kernel_func;
>>        std::string kernel_name;
>>        compat::vector<module::argument> args;
>> -      const llvm::NamedMDNode *kernel_node =
>> -                                 mod->getNamedMetadata("opencl.kernels");
>> +
>>        // XXX: Support more than one kernel
>> -      assert(kernel_node->getNumOperands() <= 1);
>> +      assert(kernels.size() == 1);
>>  
>> -      llvm::Function *kernel_func = llvm::dyn_cast<llvm::Function>(
>> -                                   kernel_node->getOperand(0)->getOperand(0));
>> +      kernel_func = kernels[0];
>>        kernel_name = kernel_func->getName();
>>  
>>        for (llvm::Function::arg_iterator I = kernel_func->arg_begin(),
>> @@ -219,9 +253,13 @@ clover::compile_program_llvm(const compat::string &source,
>>                               enum pipe_shader_ir ir,
>>                               const compat::string &triple) {
>>  
>> +   std::vector<llvm::Function *> kernels;
>> +
>>     llvm::Module *mod = compile(source, "cl_input", triple);
>>  
>> -   link(mod, triple);
>> +   find_kernels(mod, kernels);
>> +
>> +   link(mod, triple, kernels);
>>  
>>     // Build the clover::module
>>     switch (ir) {
>> @@ -230,6 +268,6 @@ clover::compile_program_llvm(const compat::string &source,
>>           assert(0);
>>           return module();
>>        default:
>> -         return build_module_llvm(mod);
>> +         return build_module_llvm(mod, kernels);
>>     }
>>  }
>> -- 
>> 1.7.7.6
>> 
>> 
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 229 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20120628/af342c15/attachment-0001.pgp>


More information about the mesa-dev mailing list