Tom Stellard <thomas.stell...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
pgp2qgiqaOnIA.pgp
Description: PGP signature
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev