[Mesa-dev] [PATCH 1/2] clover: Use a structure to hold information about llvm kernel functions

Tom Stellard thomas.stellard at amd.com
Tue Mar 24 08:25:20 PDT 2015


---
 .../state_trackers/clover/llvm/invocation.cpp      | 71 +++++++++++++---------
 1 file changed, 41 insertions(+), 30 deletions(-)

diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index 4da62b9..28198a5 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -127,6 +127,16 @@ namespace {
       return module::deserialize(cs);
    }
 #endif
+
+   struct llvm_kernel {
+
+      llvm_kernel() : fn(NULL), offset(0) {
+      }
+
+      llvm::Function *fn;
+      size_t offset;
+   };
+
    void debug_log(const std::string &msg, const std::string &suffix) {
       const char *dbg_file = debug_get_option("CLOVER_DEBUG_FILE", "stderr");
       if (!strcmp("stderr", dbg_file)) {
@@ -277,7 +287,7 @@ namespace {
    }
 
    void
-   find_kernels(llvm::Module *mod, std::vector<llvm::Function *> &kernels) {
+   find_kernels(llvm::Module *mod, std::vector<llvm_kernel> &kernels) {
       const llvm::NamedMDNode *kernel_node =
                                  mod->getNamedMetadata("opencl.kernels");
       // This means there are no kernels in the program.  The spec does not
@@ -288,18 +298,20 @@ namespace {
       }
 
       for (unsigned i = 0; i < kernel_node->getNumOperands(); ++i) {
+         kernels.resize(i + 1);
+         llvm_kernel &kernel = kernels[i];
 #if HAVE_LLVM >= 0x0306
-         kernels.push_back(llvm::mdconst::dyn_extract<llvm::Function>(
+         kernel.fn = llvm::mdconst::dyn_extract<llvm::Function>(
 #else
-         kernels.push_back(llvm::dyn_cast<llvm::Function>(
+         kernel.fn = llvm::dyn_cast<llvm::Function>(
 #endif
-                                    kernel_node->getOperand(i)->getOperand(0)));
+                                    kernel_node->getOperand(i)->getOperand(0));
       }
    }
 
    void
    optimize(llvm::Module *mod, unsigned optimization_level,
-            const std::vector<llvm::Function *> &kernels) {
+            const std::vector<llvm_kernel> &kernels) {
 
 #if HAVE_LLVM >= 0x0307
       llvm::legacy::PassManager PM;
@@ -322,10 +334,10 @@ namespace {
       // 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 *>::const_iterator I = kernels.begin(),
+      for (std::vector<llvm_kernel>::const_iterator I = kernels.begin(),
                                                          E = kernels.end();
                                                          I != E; ++I) {
-         llvm::Function *kernel = *I;
+         llvm::Function *kernel = (*I).fn;
          export_list.push_back(kernel->getName().data());
       }
 #if HAVE_LLVM < 0x0305
@@ -350,11 +362,11 @@ namespace {
    }
 
    compat::vector<module::argument>
-   get_kernel_args(const llvm::Module *mod, const std::string &kernel_name,
+   get_kernel_args(const llvm::Module *mod, const llvm_kernel &kernel,
                    const clang::LangAS::Map &address_spaces) {
 
       compat::vector<module::argument> args;
-      llvm::Function *kernel_func = mod->getFunction(kernel_name);
+      llvm::Function *kernel_func = kernel.fn;
 
 #if HAVE_LLVM < 0x0305
          llvm::DataLayout TD(kernel_func->getParent()->getDataLayout());
@@ -448,7 +460,7 @@ namespace {
 
    module
    build_module_llvm(llvm::Module *mod,
-                     const std::vector<llvm::Function *> &kernels,
+                     const std::vector<llvm_kernel> &kernels,
                      clang::LangAS::Map& address_spaces) {
 
       module m;
@@ -461,9 +473,10 @@ namespace {
       bitcode_ostream.flush();
 
       for (unsigned i = 0; i < kernels.size(); ++i) {
-         std::string kernel_name = kernels[i]->getName();
+         const llvm_kernel &kernel = kernels[i];
          compat::vector<module::argument> args =
-               get_kernel_args(mod, kernel_name, address_spaces);
+               get_kernel_args(mod, kernel, address_spaces);
+         std::string kernel_name = kernel.fn->getName().str();
 
          m.syms.push_back(module::symbol(kernel_name, 0, i, args ));
       }
@@ -555,9 +568,9 @@ namespace {
       return code;
    }
 
-   std::map<std::string, unsigned>
-   get_kernel_offsets(std::vector<char> &code,
-                      const std::vector<llvm::Function *> &kernels,
+   void
+   set_kernel_offsets(std::vector<char> &code,
+                      std::vector<llvm_kernel> &kernels,
                       compat::string &r_log) {
 
       // One of the libelf implementations
@@ -602,32 +615,29 @@ namespace {
       GElf_Sym *symbol;
       GElf_Sym s;
 
-      std::map<std::string, unsigned> kernel_offsets;
       symtab_data = elf_getdata(symtab, symtab_data);
 
       // Determine the offsets for each kernel
       for (int i = 0; (symbol = gelf_getsym(symtab_data, i, &s)); i++) {
          char *name = elf_strptr(elf, symtab_header.sh_link, symbol->st_name);
-         for (std::vector<llvm::Function*>::const_iterator it = kernels.begin(),
-              e = kernels.end(); it != e; ++it) {
-            llvm::Function *f = *it;
-            if (f->getName() == std::string(name))
-               kernel_offsets[f->getName()] = symbol->st_value;
+         for (unsigned kern_idx = 0, kern_end = kernels.size();
+              kern_idx != kern_end; ++kern_idx) {
+            llvm_kernel& kernel = kernels[kern_idx];
+            if (kernel.fn->getName() == std::string(name))
+               kernel.offset = symbol->st_value;
          }
       }
       elf_end(elf);
-      return kernel_offsets;
    }
 
    module
    build_module_native(std::vector<char> &code,
                        const llvm::Module *mod,
-                       const std::vector<llvm::Function *> &kernels,
+                       std::vector<llvm_kernel> &kernels,
                        const clang::LangAS::Map &address_spaces,
                        compat::string &r_log) {
 
-      std::map<std::string, unsigned> kernel_offsets =
-            get_kernel_offsets(code, kernels, r_log);
+      set_kernel_offsets(code, kernels, r_log);
 
       // Begin building the clover module
       module m;
@@ -641,11 +651,12 @@ namespace {
       m.secs.push_back(module::section(0, module::section::text,
                                        header.num_bytes, data));
 
-      for (std::map<std::string, unsigned>::iterator i = kernel_offsets.begin(),
-           e = kernel_offsets.end(); i != e; ++i) {
+      for (std::vector<llvm_kernel>::const_iterator i = kernels.begin(),
+                                               e = kernels.end(); i != e; ++i) {
          compat::vector<module::argument> args =
-               get_kernel_args(mod, i->first, address_spaces);
-         m.syms.push_back(module::symbol(i->first, 0, i->second, args ));
+               get_kernel_args(mod, *i, address_spaces);
+         std::string kernel_name = (*i).fn->getName().str();
+         m.syms.push_back(module::symbol(kernel_name, 0, (*i).offset, args ));
       }
 
       return m;
@@ -712,7 +723,7 @@ clover::compile_program_llvm(const compat::string &source,
 
    init_targets();
 
-   std::vector<llvm::Function *> kernels;
+   std::vector<llvm_kernel> kernels;
    size_t processor_str_len = std::string(target).find_first_of("-");
    std::string processor(target, 0, processor_str_len);
    std::string triple(target, processor_str_len + 1,
-- 
2.0.4



More information about the mesa-dev mailing list