[Mesa-dev] [PATCH 1/5] clover: Factor kernel argument parsing into its own function v2

Tom Stellard thomas.stellard at amd.com
Thu Oct 9 08:07:02 PDT 2014


v2:
  - Code cleanups.
---
 .../state_trackers/clover/llvm/invocation.cpp      | 141 +++++++++++----------
 1 file changed, 74 insertions(+), 67 deletions(-)

diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index 7bca0d6..b8badb2 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -293,96 +293,103 @@ namespace {
       PM.run(*mod);
    }
 
-   module
-   build_module_llvm(llvm::Module *mod,
-                     const std::vector<llvm::Function *> &kernels,
-                     clang::LangAS::Map& address_spaces) {
-
-      module m;
-      struct pipe_llvm_program_header header;
-
-      llvm::SmallVector<char, 1024> llvm_bitcode;
-      llvm::raw_svector_ostream bitcode_ostream(llvm_bitcode);
-      llvm::BitstreamWriter writer(llvm_bitcode);
-      llvm::WriteBitcodeToFile(mod, bitcode_ostream);
-      bitcode_ostream.flush();
-
-      for (unsigned i = 0; i < kernels.size(); ++i) {
-         llvm::Function *kernel_func;
-         std::string kernel_name;
-         compat::vector<module::argument> args;
+   compat::vector<module::argument>
+   get_kernel_args(const llvm::Module *mod, const std::string &kernel_name,
+                   const clang::LangAS::Map &address_spaces) {
 
-         kernel_func = kernels[i];
-         kernel_name = kernel_func->getName();
+      compat::vector<module::argument> args;
+      llvm::Function *kernel_func = mod->getFunction(kernel_name);
 
-         for (llvm::Function::arg_iterator I = kernel_func->arg_begin(),
+      for (llvm::Function::const_arg_iterator I = kernel_func->arg_begin(),
                                       E = kernel_func->arg_end(); I != E; ++I) {
-            llvm::Argument &arg = *I;
+         const llvm::Argument &arg = *I;
 #if HAVE_LLVM < 0x0302
-            llvm::TargetData TD(kernel_func->getParent());
+         llvm::TargetData TD(kernel_func->getParent());
 #elif HAVE_LLVM < 0x0305
-            llvm::DataLayout TD(kernel_func->getParent()->getDataLayout());
+         llvm::DataLayout TD(kernel_func->getParent()->getDataLayout());
 #else
-            llvm::DataLayout TD(mod);
+         llvm::DataLayout TD(mod);
 #endif
 
-            llvm::Type *arg_type = arg.getType();
-            const unsigned arg_store_size = TD.getTypeStoreSize(arg_type);
+         llvm::Type *arg_type = arg.getType();
+         const unsigned arg_store_size = TD.getTypeStoreSize(arg_type);
 
-            // OpenCL 1.2 specification, Ch. 6.1.5: "A built-in data
-            // type that is not a power of two bytes in size must be
-            // aligned to the next larger power of two".  We need this
-            // alignment for three element vectors, which have
-            // non-power-of-2 store size.
-            const unsigned arg_api_size =
-               util_next_power_of_two(arg_store_size);
+         // OpenCL 1.2 specification, Ch. 6.1.5: "A built-in data
+         // type that is not a power of two bytes in size must be
+         // aligned to the next larger power of two".  We need this
+         // alignment for three element vectors, which have
+         // non-power-of-2 store size.
+         const unsigned arg_api_size = util_next_power_of_two(arg_store_size);
 
-            llvm::Type *target_type = arg_type->isIntegerTy() ?
+         llvm::Type *target_type = arg_type->isIntegerTy() ?
                TD.getSmallestLegalIntType(mod->getContext(), arg_store_size * 8)
                : arg_type;
-            unsigned target_size = TD.getTypeStoreSize(target_type);
-            unsigned target_align = TD.getABITypeAlignment(target_type);
+         unsigned target_size = TD.getTypeStoreSize(target_type);
+         unsigned target_align = TD.getABITypeAlignment(target_type);
 
-            if (llvm::isa<llvm::PointerType>(arg_type) && arg.hasByValAttr()) {
-               arg_type =
+         if (llvm::isa<llvm::PointerType>(arg_type) && arg.hasByValAttr()) {
+            arg_type =
                   llvm::dyn_cast<llvm::PointerType>(arg_type)->getElementType();
-            }
+         }
 
-            if (arg_type->isPointerTy()) {
-               unsigned address_space = llvm::cast<llvm::PointerType>(arg_type)->getAddressSpace();
-               if (address_space == address_spaces[clang::LangAS::opencl_local
+         if (arg_type->isPointerTy()) {
+            unsigned address_space = llvm::cast<llvm::PointerType>(arg_type)->getAddressSpace();
+            if (address_space == address_spaces[clang::LangAS::opencl_local
                                                      - clang::LangAS::Offset]) {
-                  args.push_back(module::argument(module::argument::local,
-                                                  arg_api_size, target_size,
-                                                  target_align,
-                                                  module::argument::zero_ext));
-               } else {
-                  // XXX: Correctly handle constant address space.  There is no
-                  // way for r600g to pass a handle for constant buffers back
-                  // to clover like it can for global buffers, so
-                  // creating constant arguments will break r600g.  For now,
-                  // continue treating constant buffers as global buffers
-                  // until we can come up with a way to create handles for
-                  // constant buffers.
-                  args.push_back(module::argument(module::argument::global,
-                                                  arg_api_size, target_size,
-                                                  target_align,
-                                                  module::argument::zero_ext));
-              }
-
+               args.push_back(module::argument(module::argument::local,
+                                               arg_api_size, target_size,
+                                               target_align,
+                                               module::argument::zero_ext));
             } else {
-               llvm::AttributeSet attrs = kernel_func->getAttributes();
-               enum module::argument::ext_type ext_type =
+               // XXX: Correctly handle constant address space.  There is no
+               // way for r600g to pass a handle for constant buffers back
+               // to clover like it can for global buffers, so
+               // creating constant arguments will break r600g.  For now,
+               // continue treating constant buffers as global buffers
+               // until we can come up with a way to create handles for
+               // constant buffers.
+               args.push_back(module::argument(module::argument::global,
+                                               arg_api_size, target_size,
+                                               target_align,
+                                               module::argument::zero_ext));
+           }
+
+         } else {
+            llvm::AttributeSet attrs = kernel_func->getAttributes();
+            enum module::argument::ext_type ext_type =
                   (attrs.hasAttribute(arg.getArgNo() + 1,
                                      llvm::Attribute::SExt) ?
                    module::argument::sign_ext :
                    module::argument::zero_ext);
 
-               args.push_back(
-                  module::argument(module::argument::scalar, arg_api_size,
-                                   target_size, target_align, ext_type));
-            }
+            args.push_back(
+               module::argument(module::argument::scalar, arg_api_size,
+                                target_size, target_align, ext_type));
          }
+      }
+      return args;
+   }
+
+   module
+   build_module_llvm(llvm::Module *mod,
+                     const std::vector<llvm::Function *> &kernels,
+                     clang::LangAS::Map& address_spaces) {
+
+      module m;
+      struct pipe_llvm_program_header header;
+
+      llvm::SmallVector<char, 1024> llvm_bitcode;
+      llvm::raw_svector_ostream bitcode_ostream(llvm_bitcode);
+      llvm::BitstreamWriter writer(llvm_bitcode);
+      llvm::WriteBitcodeToFile(mod, bitcode_ostream);
+      bitcode_ostream.flush();
+
+      for (unsigned i = 0; i < kernels.size(); ++i) {
+         std::string kernel_name;
+         compat::vector<module::argument> args;
+
+         kernel_name = kernels[i]->getName();
+         args = get_kernel_args(mod, kernel_name, address_spaces);
 
          m.syms.push_back(module::symbol(kernel_name, 0, i, args ));
       }
-- 
1.8.5.5



More information about the mesa-dev mailing list