clover: Handle multiple kernels in the same program v2
authorBlaž Tomažič <blaz.tomazic@gmail.com>
Thu, 13 Sep 2012 14:51:46 +0000 (14:51 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Tue, 25 Sep 2012 14:27:47 +0000 (14:27 +0000)
v2: Tom Stellard
  - Use pc parameter of launch_grid()

Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
src/gallium/include/pipe/p_context.h
src/gallium/state_trackers/clover/llvm/invocation.cpp

index f59e388123292a9d9f80064011e8af3b56e62467..5d4681277793c80ee5d842c0f15cd7449c72f6f6 100644 (file)
@@ -507,6 +507,10 @@ struct pipe_context {
     * grid (in block units) and working block (in thread units) to be
     * used, respectively.
     *
+    * \a pc For drivers that use PIPE_SHADER_IR_LLVM as their prefered IR,
+    * this value will be the index of the kernel in the opencl.kernels
+    * metadata list.
+    *
     * \a input will be used to initialize the INPUT resource, and it
     * should point to a buffer of at least
     * pipe_compute_state::req_input_mem bytes.
index be15e960b18ad90441f35a02cfbddd8a49a09201..6ab9025f209279156ef037b287c6de11489cf309 100644 (file)
@@ -199,41 +199,42 @@ namespace {
       llvm::WriteBitcodeToFile(mod, bitcode_ostream);
       bitcode_ostream.flush();
 
-      llvm::Function *kernel_func;
-      std::string kernel_name;
-      compat::vector<module::argument> args;
-
-      // XXX: Support more than one kernel
-      assert(kernels.size() == 1);
-
-      kernel_func = kernels[0];
-      kernel_name = kernel_func->getName();
-
-      for (llvm::Function::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();
-         llvm::TargetData TD(kernel_func->getParent());
-         unsigned arg_size = TD.getTypeStoreSize(arg_type);
-
-         if (llvm::isa<llvm::PointerType>(arg_type) && arg.hasByValAttr()) {
-            arg_type =
-               llvm::dyn_cast<llvm::PointerType>(arg_type)->getElementType();
-         }
+      for (unsigned i = 0; i < kernels.size(); ++i) {
+         llvm::Function *kernel_func;
+         std::string kernel_name;
+         compat::vector<module::argument> args;
+
+         kernel_func = kernels[i];
+         kernel_name = kernel_func->getName();
+
+         for (llvm::Function::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();
+            llvm::TargetData TD(kernel_func->getParent());
+            unsigned arg_size = TD.getTypeStoreSize(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()) {
-            // XXX: Figure out LLVM->OpenCL address space mappings for each
-            // target.  I think we need to ask clang what these are.  For now,
-            // pretend everything is in the global address space.
-            unsigned address_space = llvm::cast<llvm::PointerType>(arg_type)->getAddressSpace();
-            switch (address_space) {
-               default:
-                  args.push_back(module::argument(module::argument::global, arg_size));
-                  break;
+            if (arg_type->isPointerTy()) {
+               // XXX: Figure out LLVM->OpenCL address space mappings for each
+               // target.  I think we need to ask clang what these are.  For now,
+               // pretend everything is in the global address space.
+               unsigned address_space = llvm::cast<llvm::PointerType>(arg_type)->getAddressSpace();
+               switch (address_space) {
+                  default:
+                     args.push_back(module::argument(module::argument::global, arg_size));
+                     break;
+               }
+            } else {
+               args.push_back(module::argument(module::argument::scalar, arg_size));
             }
-         } else {
-            args.push_back(module::argument(module::argument::scalar, arg_size));
          }
+
+         m.syms.push_back(module::symbol(kernel_name, 0, i, args ));
       }
 
       header.num_bytes = llvm_bitcode.size();
@@ -241,7 +242,6 @@ namespace {
       data.insert(0, (char*)(&header), sizeof(header));
       data.insert(data.end(), llvm_bitcode.begin(),
                                   llvm_bitcode.end());
-      m.syms.push_back(module::symbol(kernel_name, 0, 0, args ));
       m.secs.push_back(module::section(0, module::section::text,
                                        header.num_bytes, data));