clover: Factor kernel argument parsing into its own function v2
authorTom Stellard <thomas.stellard@amd.com>
Thu, 25 Sep 2014 13:04:25 +0000 (09:04 -0400)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 16 Oct 2014 23:42:14 +0000 (19:42 -0400)
v2:
  - Code cleanups.

Reviewed-by: Francisco Jerez <currojerez@riseup.net>
src/gallium/state_trackers/clover/llvm/invocation.cpp

index 212b4e48f622e13aa6c7269bff088ddfaaeee061..41f1d6a47bf2eed1f70215d8ceab143acafcb651 100644 (file)
@@ -293,23 +293,13 @@ namespace {
       PM.run(*mod);
    }
 
-   module
-   build_module_llvm(llvm::Module *mod,
-                     const std::vector<llvm::Function *> &kernels,
-                     clang::LangAS::Map& address_spaces) {
+   compat::vector<module::argument>
+   get_kernel_args(const llvm::Module *mod, const std::string &kernel_name,
+                   const 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();
+      compat::vector<module::argument> args;
+      llvm::Function *kernel_func = mod->getFunction(kernel_name);
 
-      for (unsigned i = 0; i < kernels.size(); ++i) {
-         llvm::Function *kernel_func = kernels[i];
-         const std::string kernel_name = kernel_func->getName();
 #if HAVE_LLVM < 0x0302
          llvm::TargetData TD(kernel_func->getParent());
 #elif HAVE_LLVM < 0x0305
@@ -317,88 +307,109 @@ namespace {
 #else
          llvm::DataLayout TD(mod);
 #endif
-         compat::vector<module::argument> args;
 
-         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;
-            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);
-
-            llvm::Type *target_type = arg_type->isIntegerTy() ?
+         const llvm::Argument &arg = *I;
+
+         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);
+
+         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));
          }
+      }
+
+      // Append implicit arguments.  XXX - The types, ordering and
+      // vector size of the implicit arguments should depend on the
+      // target according to the selected calling convention.
+      llvm::Type *size_type =
+         TD.getSmallestLegalIntType(mod->getContext(), sizeof(cl_uint) * 8);
+
+      args.push_back(
+         module::argument(module::argument::scalar, sizeof(cl_uint),
+                          TD.getTypeStoreSize(size_type),
+                          TD.getABITypeAlignment(size_type),
+                          module::argument::zero_ext,
+                          module::argument::grid_dimension));
+
+      args.push_back(
+         module::argument(module::argument::scalar, sizeof(cl_uint),
+                          TD.getTypeStoreSize(size_type),
+                          TD.getABITypeAlignment(size_type),
+                          module::argument::zero_ext,
+                          module::argument::grid_offset));
+
+      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;
 
-         // Append implicit arguments.  XXX - The types, ordering and
-         // vector size of the implicit arguments should depend on the
-         // target according to the selected calling convention.
-         llvm::Type *size_type =
-            TD.getSmallestLegalIntType(mod->getContext(), sizeof(cl_uint) * 8);
-
-         args.push_back(
-            module::argument(module::argument::scalar, sizeof(cl_uint),
-                             TD.getTypeStoreSize(size_type),
-                             TD.getABITypeAlignment(size_type),
-                             module::argument::zero_ext,
-                             module::argument::grid_dimension));
-
-         args.push_back(
-            module::argument(module::argument::scalar, sizeof(cl_uint),
-                             TD.getTypeStoreSize(size_type),
-                             TD.getABITypeAlignment(size_type),
-                             module::argument::zero_ext,
-                             module::argument::grid_offset));
+      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 = kernels[i]->getName();
+         compat::vector<module::argument> args =
+               get_kernel_args(mod, kernel_name, address_spaces);
 
          m.syms.push_back(module::symbol(kernel_name, 0, i, args ));
       }