[Beignet] [PATCH OCL20 v2 2/4] Backend: Add Pipe Builtin support
Xiuli Pan
xiuli.pan at intel.com
Tue Mar 1 04:47:56 UTC 2016
From: Pan Xiuli <xiuli.pan at intel.com>
Add pipe builtin functions
v2: Refine type size to be system determined
Signed-off-by: Pan Xiuli <xiuli.pan at intel.com>
---
backend/src/backend/context.cpp | 5 +
backend/src/backend/gen_reg_allocation.cpp | 3 +-
backend/src/backend/program.h | 1 +
backend/src/ir/function.cpp | 1 +
backend/src/ir/function.hpp | 9 +-
backend/src/libocl/CMakeLists.txt | 2 +-
backend/src/libocl/include/ocl.h | 1 +
backend/src/libocl/include/ocl_pipe.h | 51 +++++
backend/src/libocl/src/ocl_pipe.cl | 296 +++++++++++++++++++++++++++++
backend/src/llvm/llvm_gen_backend.cpp | 61 +++++-
backend/src/llvm/llvm_gen_ocl_function.hxx | 5 +
src/cl_command_queue.c | 2 +-
src/cl_kernel.c | 5 +-
13 files changed, 427 insertions(+), 15 deletions(-)
create mode 100644 backend/src/libocl/include/ocl_pipe.h
create mode 100644 backend/src/libocl/src/ocl_pipe.cl
diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp
index 9236022..40b744f 100644
--- a/backend/src/backend/context.cpp
+++ b/backend/src/backend/context.cpp
@@ -466,6 +466,11 @@ namespace gbe
kernel->args[argID].type = GBE_ARG_SAMPLER;
kernel->args[argID].size = sizeof(void*);
break;
+ case ir::FunctionArgument::PIPE:
+ kernel->args[argID].type = GBE_ARG_PIPE;
+ kernel->args[argID].size = sizeof(void*);
+ kernel->args[argID].bti = arg.bti;
+ break;
}
}
}
diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp
index a9338c5..9339f0f 100644
--- a/backend/src/backend/gen_reg_allocation.cpp
+++ b/backend/src/backend/gen_reg_allocation.cpp
@@ -1310,7 +1310,8 @@ namespace gbe
const ir::FunctionArgument &arg = this->opaque->ctx.getFunction().getArg(subType);
if (arg.type == ir::FunctionArgument::GLOBAL_POINTER ||
arg.type == ir::FunctionArgument::LOCAL_POINTER ||
- arg.type == ir::FunctionArgument::CONSTANT_POINTER)
+ arg.type == ir::FunctionArgument::CONSTANT_POINTER||
+ arg.type == ir::FunctionArgument::PIPE)
regSize = this->opaque->ctx.getPointerSize();
else
regSize = arg.size;
diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h
index e300140..a84ddb1 100644
--- a/backend/src/backend/program.h
+++ b/backend/src/backend/program.h
@@ -50,6 +50,7 @@ enum gbe_arg_type {
GBE_ARG_LOCAL_PTR = 3, // __local
GBE_ARG_IMAGE = 4, // image2d_t, image3d_t
GBE_ARG_SAMPLER = 5, // sampler_t
+ GBE_ARG_PIPE = 6, // pipe
GBE_ARG_INVALID = 0xffffffff
};
diff --git a/backend/src/ir/function.cpp b/backend/src/ir/function.cpp
index 00fe97c..f09cbe3 100644
--- a/backend/src/ir/function.cpp
+++ b/backend/src/ir/function.cpp
@@ -321,6 +321,7 @@ namespace ir {
out << "structure." << input.size;
break;
case FunctionArgument::IMAGE: out << "image"; break;
+ case FunctionArgument::PIPE: out << "pipe"; break;
default: break;
}
out << " %" << input.reg << " " << input.name << std::endl;
diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp
index ba589a3..4b076e6 100644
--- a/backend/src/ir/function.hpp
+++ b/backend/src/ir/function.hpp
@@ -170,8 +170,9 @@ namespace ir {
LOCAL_POINTER = 2, // __local
VALUE = 3, // int, float
STRUCTURE = 4, // struct foo
- IMAGE = 5, // image*d_t
- SAMPLER = 6
+ IMAGE = 5, // image*d_t
+ SAMPLER = 6,
+ PIPE = 7 // pipe
};
struct InfoFromLLVM { // All the info about passed by llvm, using -cl-kernel-arg-info
@@ -209,6 +210,10 @@ namespace ir {
return typeName.compare("sampler_t") == 0;
}
+ bool isPipeType() const {
+ return typeQual.compare("pipe") == 0;
+ }
+
};
/*! Create a function input argument */
diff --git a/backend/src/libocl/CMakeLists.txt b/backend/src/libocl/CMakeLists.txt
index 8bb4c1e..f17400a 100644
--- a/backend/src/libocl/CMakeLists.txt
+++ b/backend/src/libocl/CMakeLists.txt
@@ -53,7 +53,7 @@ FOREACH(M ${OCL_COPY_HEADERS})
ENDFOREACH(M)
SET (OCL_COPY_MODULES ocl_workitem ocl_atom ocl_async ocl_sync ocl_memcpy
- ocl_memset ocl_misc ocl_vload ocl_geometric ocl_image ocl_work_group)
+ ocl_memset ocl_misc ocl_vload ocl_geometric ocl_image ocl_work_group ocl_pipe)
FOREACH(M ${OCL_COPY_MODULES})
COPY_THE_HEADER(${M})
COPY_THE_SOURCE(${M})
diff --git a/backend/src/libocl/include/ocl.h b/backend/src/libocl/include/ocl.h
index abb2bd4..e2918c6 100644
--- a/backend/src/libocl/include/ocl.h
+++ b/backend/src/libocl/include/ocl.h
@@ -40,6 +40,7 @@
#include "ocl_workitem.h"
#include "ocl_simd.h"
#include "ocl_work_group.h"
+#include "ocl_pipe.h"
#pragma OPENCL EXTENSION cl_khr_fp64 : disable
#pragma OPENCL EXTENSION cl_khr_fp16 : disable
#endif
diff --git a/backend/src/libocl/include/ocl_pipe.h b/backend/src/libocl/include/ocl_pipe.h
new file mode 100644
index 0000000..349b1dd
--- /dev/null
+++ b/backend/src/libocl/include/ocl_pipe.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2012 - 2014 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#ifndef __OCL_PIPE_H__
+#define __OCL_PIPE_H__
+
+#include "ocl_types.h"
+#include "ocl_work_group.h"
+#include "ocl_simd.h"
+
+/* The pipe read function. */
+int __read_pipe_2(pipe int p, __generic void* dst);
+int __read_pipe_4(pipe int p, reserve_id_t id, uint index, void* dst);
+reserve_id_t __reserve_read_pipe(pipe int p, uint num);
+void __commit_read_pipe(pipe int p, reserve_id_t rid);
+reserve_id_t __work_group_reserve_read_pipe(pipe int p, uint num);
+void __work_group_commit_read_pipe(pipe int p, reserve_id_t rid);
+reserve_id_t __sub_group_reserve_read_pipe(pipe int p, uint num);
+void __sub_group_commit_read_pipe(pipe int p, reserve_id_t rid);
+
+/* The pipe write function. */
+int __write_pipe_2(pipe int p, __generic void* src);
+int __write_pipe_4(pipe int p, reserve_id_t id, uint index, void* src);
+reserve_id_t __reserve_write_pipe(pipe int p, uint num);
+void __commit_write_pipe(pipe int p, reserve_id_t rid);
+reserve_id_t __work_group_reserve_write_pipe(pipe int p, uint num);
+void __work_group_commit_write_pipe(pipe int p, reserve_id_t rid);
+reserve_id_t __sub_group_reserve_write_pipe(pipe int p, uint num);
+void __sub_group_commit_write_pipe(pipe int p, reserve_id_t rid);
+
+/* The reserve_id_t function. */
+bool is_valid_reserve_id(reserve_id_t rid);
+
+/* The pipe query function. */
+uint __get_pipe_num_packets(pipe int p);
+uint __get_pipe_max_packets(pipe int p);
+#endif
diff --git a/backend/src/libocl/src/ocl_pipe.cl b/backend/src/libocl/src/ocl_pipe.cl
new file mode 100644
index 0000000..7bfd370
--- /dev/null
+++ b/backend/src/libocl/src/ocl_pipe.cl
@@ -0,0 +1,296 @@
+/*
+ * Copyright © 2012 - 2014 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "ocl_pipe.h"
+#include "ocl_atom.h"
+#include "ocl_workitem.h"
+
+#define PIPE_SUCCESS 0
+#define PIPE_EMPTY -2
+#define PIPE_FULL -3
+#define PIPE_HEADER_SZ 128
+#define PIPE_INDEX_OUTRANGE -4
+#define PIPE_RESERVE_FAIL -5
+#define RID_MAGIC 0xDE
+#define RIDT ushort
+#define DEAD_PTR 0xFFFFFFFF
+
+PURE CONST __global void* __gen_ocl_get_pipe(pipe int p);
+PURE CONST ulong __gen_ocl_get_rid(reserve_id_t rid);
+PURE CONST reserve_id_t __gen_ocl_make_rid(ulong rid);
+
+int __read_pipe_2(pipe int p, __generic void* dst)
+{
+ __global int* pheader = (__global int*)__gen_ocl_get_pipe(p);
+ int data_size = atomic_sub(pheader + 6, 1);
+ if(data_size < 0){
+ atomic_add(pheader + 6, 1);
+ return PIPE_EMPTY; //Check if element exist
+ }
+ __global char* psrc = (__global char*)pheader + PIPE_HEADER_SZ;
+ int pack_num = pheader[0];
+ int pack_size = pheader[1];
+ int pipe_size = pack_num * pack_size;
+ int read_ptr = atomic_add(pheader + 3, 1);
+ if(read_ptr == pack_num - 1)
+ atomic_sub(pheader + 3, pack_num);
+ read_ptr = read_ptr % pack_num;
+ for(int i = 0; i < pack_size ; i++)
+ ((char*)dst)[i] = psrc[i + read_ptr*pack_size];
+ return 0;
+}
+
+int __read_pipe_4(pipe int p, reserve_id_t id, uint index, void* dst)
+{
+ __global int* pheader = (__global int*)__gen_ocl_get_pipe(p);
+ __global char* psrc = (__global char*)pheader + PIPE_HEADER_SZ;
+ ulong uid = __gen_ocl_get_rid(id);
+ RIDT* pid = (RIDT*)&uid;
+ RIDT start_pt = pid[0];
+ RIDT reserve_size = pid[1];
+ if(index > reserve_size) return PIPE_INDEX_OUTRANGE;
+ int pack_num = pheader[0];
+ int pack_size = pheader[1];
+ int read_ptr = (start_pt + index) % pack_num;
+ int offset = read_ptr * pack_size;
+ for(int i = 0; i < pack_size ; i++)
+ ((char*)dst)[i] = psrc[i + offset];
+ return 0;
+}
+
+
+int __write_pipe_2(pipe int p, __generic void* src)
+{
+ __global int* pheader = (__global int*)__gen_ocl_get_pipe(p);
+ int pack_num = pheader[0];
+ int data_size = atomic_add(pheader + 6, 1);
+ if(data_size >= pack_num){
+ atomic_sub(pheader + 6, 1);
+ return PIPE_FULL; //Check if pipe full
+ }
+ __global char* psrc = (__global char*)pheader + PIPE_HEADER_SZ;
+ int pack_size = pheader[1];
+ int pipe_size = pack_num * pack_size;
+ int write_ptr = atomic_add(pheader + 2, 1);
+ if(write_ptr == pack_num - 1)
+ atomic_sub(pheader + 2, pack_num);
+ write_ptr = write_ptr % pack_num;
+ for(int i = 0; i < pack_size ; i++)
+ psrc[i + write_ptr * pack_size] = ((char*)src)[i];
+ return 0;
+}
+
+int __write_pipe_4(pipe int p, reserve_id_t id, uint index, void* src)
+{
+ __global int* pheader = __gen_ocl_get_pipe(p);
+ __global char* psrc = (__global char*)pheader + PIPE_HEADER_SZ;
+ ulong uid = __gen_ocl_get_rid(id);
+ RIDT* pid = (RIDT*)&uid;
+ RIDT start_pt = pid[0];
+ RIDT reserve_size = pid[1];
+ if(index > reserve_size) return PIPE_INDEX_OUTRANGE;
+ int pack_num = pheader[0];
+ int pack_size = pheader[1];
+ int write_ptr = (start_pt + index) % pack_num;
+ int offset = write_ptr * pack_size;
+ for(int i = 0; i < pack_size ; i++)
+ psrc[i + offset] = ((char*)src)[i];
+ return pack_size;
+}
+
+reserve_id_t __reserve_read_pipe(pipe int p, uint num)
+{
+ __global int* pheader = (__global int*)__gen_ocl_get_pipe(p);
+ int data_size = atomic_sub(pheader + 6, num);
+ if(data_size < num){
+ atomic_add(pheader + 6, num);
+ return __gen_ocl_make_rid(0l);
+ }
+ int pack_num = pheader[0];
+ int pack_size = pheader[1];
+ int pipe_size = pack_num * pack_size;
+ int read_ptr = atomic_add(pheader + 3, num);
+ if(read_ptr == pack_num - num)
+ atomic_sub(pheader + 3, pack_num);
+ ulong uid = 0l;
+ RIDT* pid = (RIDT*)&uid;
+ pid[0] = read_ptr % pack_num;
+ pid[1] = num;
+ pid[2] = RID_MAGIC ;
+ return __gen_ocl_make_rid(uid);
+}
+
+void __commit_read_pipe(pipe int p, reserve_id_t rid) {}
+
+reserve_id_t __work_group_reserve_read_pipe(pipe int p, uint num)
+{
+ uint rid_ptr = DEAD_PTR;
+ int ret0 = 0;
+ if(get_local_linear_id()==0){
+ __global int* pheader = (__global int*)__gen_ocl_get_pipe(p);
+ int data_size = atomic_sub(pheader + 6, num);
+ if(data_size < num){
+ atomic_add(pheader + 6, num);
+ int ret0 = 1;
+ }
+ int pack_num = pheader[0];
+ int pack_size = pheader[1];
+ int pipe_size = pack_num * pack_size;
+ int read_ptr = atomic_add(pheader + 3, num);
+ if(read_ptr == pack_num - num && !ret0)
+ atomic_sub(pheader + 3, pack_num);
+ if(!ret0)
+ rid_ptr = read_ptr % pack_num;
+ }
+ ulong uid = 0l;
+ RIDT* pid = (RIDT*)&uid;
+ rid_ptr = work_group_broadcast(rid_ptr,0,0,0);
+ pid[0] = rid_ptr;
+ pid[1] = num;
+ pid[2] = RID_MAGIC ;
+ if(rid_ptr == DEAD_PTR)
+ uid = 0l;
+ return __gen_ocl_make_rid(uid);
+}
+
+void __work_group_commit_read_pipe(pipe int p, reserve_id_t rid) {}
+
+reserve_id_t __sub_group_reserve_read_pipe(pipe int p, uint num)
+{
+ __global int* pheader = (__global int*)__gen_ocl_get_pipe(p);
+ int data_size = atomic_sub(pheader + 6, num);
+ if(data_size < num){
+ atomic_add(pheader + 6, num);
+ return __gen_ocl_make_rid(0l);
+ }
+ int pack_num = pheader[0];
+ int pack_size = pheader[1];
+ int pipe_size = pack_num * pack_size;
+ int read_ptr = atomic_add(pheader + 3, num);
+ if(read_ptr == pack_num - num)
+ atomic_sub(pheader + 3, pack_num);
+ ulong uid = 0l;
+ RIDT* pid = (RIDT*)&uid;
+ pid[0] = read_ptr % pack_num;
+ pid[1] = num;
+ pid[2] = RID_MAGIC ;
+ return __gen_ocl_make_rid(uid);
+}
+
+void __sub_group_commit_read_pipe(pipe int p, reserve_id_t rid) {}
+
+reserve_id_t __reserve_write_pipe(pipe int p, uint num)
+{
+ __global int* pheader = (__global int*)__gen_ocl_get_pipe(p);
+ int pack_num = pheader[0];
+ int data_size = atomic_add(pheader + 6, num);
+ if(data_size > pack_num - num){
+ atomic_sub(pheader + 6, num);
+ return __gen_ocl_make_rid(0l);
+ }
+ int pack_size = pheader[1];
+ int pipe_size = pack_num * pack_size;
+ int write_ptr = atomic_add(pheader + 2, num);
+ if(write_ptr == pack_num - num)
+ atomic_sub(pheader + 2, pack_num);
+ ulong uid = 0l;
+ RIDT* pid = (RIDT*)&uid;
+ pid[0] = write_ptr % pack_num;
+ pid[1] = num;
+ pid[2] = RID_MAGIC ;
+ return __gen_ocl_make_rid(uid);
+}
+void __commit_write_pipe(pipe int p, reserve_id_t rid) {}
+
+reserve_id_t __work_group_reserve_write_pipe(pipe int p, uint num)
+{
+ uint rid_ptr = DEAD_PTR;
+ int ret0 = 0;
+ if(get_local_linear_id()==0){
+ __global int* pheader = (__global int*)__gen_ocl_get_pipe(p);
+ int pack_num = pheader[0];
+ int data_size = atomic_add(pheader + 6, num);
+ if(data_size > pack_num - num){
+ atomic_sub(pheader + 6, num);
+ ret0 = 1;
+ }
+ int pack_size = pheader[1];
+ int pipe_size = pack_num * pack_size;
+ int write_ptr = atomic_add(pheader + 2, num);
+ if(write_ptr == pack_num - num && !ret0)
+ atomic_sub(pheader + 2, pack_num);
+ if(!ret0)
+ rid_ptr = write_ptr % pack_num;
+ }
+ ulong uid = 0l;
+ RIDT* pid = (RIDT*)&uid;
+ rid_ptr = work_group_broadcast(rid_ptr,0,0,0);
+ pid[0] = rid_ptr;
+ pid[1] = num;
+ pid[2] = RID_MAGIC ;
+ if(rid_ptr == DEAD_PTR)
+ uid = 0l;
+ return __gen_ocl_make_rid(uid);
+}
+void __work_group_commit_write_pipe(pipe int p, reserve_id_t rid) {}
+
+
+reserve_id_t __sub_group_reserve_write_pipe(pipe int p, uint num)
+{
+ __global int* pheader = (__global int*)__gen_ocl_get_pipe(p);
+ int pack_num = pheader[0];
+ int data_size = atomic_add(pheader + 6, num);
+ if(data_size > pack_num - num){
+ atomic_sub(pheader + 6, num);
+ return __gen_ocl_make_rid(0l);
+ }
+ int pack_size = pheader[1];
+ int pipe_size = pack_num * pack_size;
+ int write_ptr = atomic_add(pheader + 2, num);
+ if(write_ptr == pack_num - num)
+ atomic_sub(pheader + 2, pack_num);
+ ulong uid = 0l;
+ RIDT* pid = (RIDT*)&uid;
+ pid[0] = write_ptr % pack_num;
+ pid[1] = num;
+ pid[2] = RID_MAGIC ;
+ return __gen_ocl_make_rid(uid);
+}
+
+void __sub_group_commit_write_pipe(pipe int p, reserve_id_t rid) {}
+
+bool is_valid_reserve_id(reserve_id_t rid)
+{
+ ulong uid = __gen_ocl_get_rid(rid);
+ RIDT* pid = (RIDT*)&uid;
+ if(pid[1] == 0) return false;
+ if(pid[2] != RID_MAGIC) return false;
+ return true;
+}
+
+/* Query Function */
+uint __get_pipe_max_packets(pipe int p)
+{
+ __global int* pheader = __gen_ocl_get_pipe(p);
+ return pheader[0];
+}
+
+uint __get_pipe_num_packets(pipe int p)
+{
+ __global int* pheader = __gen_ocl_get_pipe(p);
+ return pheader[6];
+}
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index d5d02f5..7f5b642 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -843,12 +843,25 @@ namespace gbe
visited.insert(theUser);
if (isa<LoadInst>(theUser) || isa<StoreInst>(theUser) || isa<CallInst>(theUser)) {
+ Value *pointer = NULL;
if (isa<CallInst>(theUser)) {
Function *F = dyn_cast<CallInst>(theUser)->getCalledFunction();
- if (!F || F->getIntrinsicID() != 0) continue;
+ if(!F) continue;
+ // get pipe function to convert pipe to ptr
+ const std::string fnName = F->getName();
+ auto genIntrinsicID = intrinsicMap.find(fnName);
+ if(genIntrinsicID == GEN_OCL_GET_PIPE){
+ pointer = theUser;
+ revisit.push_back(theUser);
+ }
+ else if (F->getIntrinsicID() != 0) continue;
+ else{
+ // atomic/read(write)image
+ CallInst *ci = dyn_cast<CallInst>(theUser);
+ pointer = ci->getArgOperand(0);
+ }
}
- Value *pointer = NULL;
- if (isa<LoadInst>(theUser)) {
+ else if (isa<LoadInst>(theUser)) {
ptrCandidate.insert(cast<LoadInst>(theUser));
pointer = dyn_cast<LoadInst>(theUser)->getPointerOperand();
} else if (isa<StoreInst>(theUser)) {
@@ -858,10 +871,6 @@ namespace gbe
if (addrStoreInst.find(theUser) != addrStoreInst.end()) {
isPointerArray = true;
}
- } else if (isa<CallInst>(theUser)) {
- // atomic/read(write)image
- CallInst *ci = dyn_cast<CallInst>(theUser);
- pointer = ci->getArgOperand(0);
} else {
theUser->dump();
GBE_ASSERT(0 && "Unknown instruction operating on pointers\n");
@@ -1151,6 +1160,7 @@ namespace gbe
BtiMap.insert(std::make_pair(&v, getNewBti(&v, false)));
}
MDNode *typeNameNode = NULL;
+ MDNode *typeQualNode = NULL;
MDNode *node = getKernelFunctionMetadata(&F);
for(uint j = 0; j < node->getNumOperands() - 1; j++) {
MDNode *attrNode = dyn_cast_or_null<MDNode>(node->getOperand(1 + j));
@@ -1159,6 +1169,8 @@ namespace gbe
if (!attrName) continue;
if (attrName->getString() == "kernel_arg_type") {
typeNameNode = attrNode;
+ } else if (attrName->getString() == "kernel_arg_type_qual") {
+ typeQualNode = attrNode;
}
}
@@ -1166,9 +1178,11 @@ namespace gbe
ir::FunctionArgument::InfoFromLLVM llvmInfo;
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I, argID++) {
llvmInfo.typeName= (cast<MDString>(typeNameNode->getOperand(1 + argID)))->getString();
+ llvmInfo.typeQual = (cast<MDString>(typeQualNode->getOperand(1 + argID)))->getString();
bool isImage = llvmInfo.isImageType();
- if (I->getType()->isPointerTy() || isImage) {
- BtiMap.insert(std::make_pair(&*I, getNewBti(&*I, isImage)));
+ bool isPipe = llvmInfo.isPipeType();
+ if (I->getType()->isPointerTy() || isImage || isPipe) {
+ BtiMap.insert(std::make_pair(&*I, getNewBti(&*I, isImage || isPipe)));
}
}
@@ -1263,6 +1277,7 @@ namespace gbe
}
void GenWriter::analyzePointerOrigin(Function &F) {
+
// used to record where the pointers get mixed (i.e. select or phi instruction)
std::set<Value *> mixedPtr;
// This is a two-pass algorithm, the 1st pass will try to update the pointer sources for
@@ -2050,6 +2065,10 @@ namespace gbe
(void)ctx.getFunction().getSamplerSet()->append(reg, &ctx);
continue;
}
+ if(llvmInfo.isPipeType()) {
+ ctx.input(argName, ir::FunctionArgument::PIPE, reg, llvmInfo, getTypeByteSize(unit, type), getAlignmentByte(unit, type), BtiMap.find(&*I)->second);
+ continue;
+ }
if (type->isPointerTy() == false)
ctx.input(argName, ir::FunctionArgument::VALUE, reg, llvmInfo, getTypeByteSize(unit, type), getAlignmentByte(unit, type), 0);
@@ -3621,6 +3640,24 @@ namespace gbe
case GEN_OCL_WORK_GROUP_SCAN_INCLUSIVE_MIN:
this->newRegister(&I);
break;
+ case GEN_OCL_GET_PIPE:
+ {
+ Value *srcValue = I.getOperand(0);
+ if( BtiMap.find(dst) == BtiMap.end())
+ {
+ unsigned tranBti = BtiMap.find(srcValue)->second;
+ BtiMap.insert(std::make_pair(dst, tranBti));
+ }
+ regTranslator.newValueProxy(srcValue, dst);
+ break;
+ }
+ case GEN_OCL_MAKE_RID:
+ case GEN_OCL_GET_RID:
+ {
+ Value *srcValue = I.getOperand(0);
+ regTranslator.newValueProxy(srcValue, dst);
+ break;
+ }
case GEN_OCL_PRINTF:
break;
case GEN_OCL_NOT_FOUND:
@@ -4450,6 +4487,12 @@ namespace gbe
this->emitWorkGroupInst(I, CS, ir::WORKGROUP_OP_INCLUSIVE_MAX); break;
case GEN_OCL_WORK_GROUP_SCAN_INCLUSIVE_MIN:
this->emitWorkGroupInst(I, CS, ir::WORKGROUP_OP_INCLUSIVE_MIN); break;
+ case GEN_OCL_GET_PIPE:
+ case GEN_OCL_MAKE_RID:
+ case GEN_OCL_GET_RID:
+ {
+ break;
+ }
default: break;
}
}
diff --git a/backend/src/llvm/llvm_gen_ocl_function.hxx b/backend/src/llvm/llvm_gen_ocl_function.hxx
index 92d4ea3..7bd59fc 100644
--- a/backend/src/llvm/llvm_gen_ocl_function.hxx
+++ b/backend/src/llvm/llvm_gen_ocl_function.hxx
@@ -189,3 +189,8 @@ DECL_LLVM_GEN_FUNCTION(WORK_GROUP_SCAN_INCLUSIVE_MIN, __gen_ocl_work_group_scan_
DECL_LLVM_GEN_FUNCTION(WORK_GROUP_ALL, __gen_ocl_work_group_all)
DECL_LLVM_GEN_FUNCTION(WORK_GROUP_ANY, __gen_ocl_work_group_any)
+
+// pipe function
+DECL_LLVM_GEN_FUNCTION(GET_PIPE, __gen_ocl_get_pipe)
+DECL_LLVM_GEN_FUNCTION(GET_RID, __gen_ocl_get_rid)
+DECL_LLVM_GEN_FUNCTION(MAKE_RID, __gen_ocl_make_rid)
diff --git a/src/cl_command_queue.c b/src/cl_command_queue.c
index 442c6a2..effb30b 100644
--- a/src/cl_command_queue.c
+++ b/src/cl_command_queue.c
@@ -161,7 +161,7 @@ cl_command_queue_bind_surface(cl_command_queue queue, cl_kernel k)
for (i = 0; i < k->arg_n; ++i) {
int32_t offset; // location of the address in the curbe
arg_type = interp_kernel_get_arg_type(k->opaque, i);
- if (!(arg_type == GBE_ARG_GLOBAL_PTR || arg_type == GBE_ARG_CONSTANT_PTR) || !k->args[i].mem)
+ if (!(arg_type == GBE_ARG_GLOBAL_PTR || arg_type == GBE_ARG_CONSTANT_PTR || arg_type == GBE_ARG_PIPE) || !k->args[i].mem)
continue;
offset = interp_kernel_get_curbe_offset(k->opaque, GBE_CURBE_KERNEL_ARGUMENT, i);
if (offset < 0)
diff --git a/src/cl_kernel.c b/src/cl_kernel.c
index 723eac3..abbabbd 100644
--- a/src/cl_kernel.c
+++ b/src/cl_kernel.c
@@ -136,7 +136,8 @@ cl_kernel_set_arg(cl_kernel k, cl_uint index, size_t sz, const void *value)
return CL_INVALID_SAMPLER;
} else {
// should be image, GLOBAL_PTR, CONSTANT_PTR
- if (UNLIKELY(value == NULL && arg_type == GBE_ARG_IMAGE))
+ if (UNLIKELY(value == NULL && (arg_type == GBE_ARG_IMAGE ||
+ arg_type == GBE_ARG_PIPE)))
return CL_INVALID_ARG_VALUE;
if(value != NULL)
mem = *(cl_mem*)value;
@@ -331,6 +332,8 @@ cl_get_kernel_arg_info(cl_kernel k, cl_uint arg_index, cl_kernel_arg_info param_
type_qual = type_qual | CL_KERNEL_ARG_TYPE_VOLATILE;
if (strstr((char*)ret_info, "restrict"))
type_qual = type_qual | CL_KERNEL_ARG_TYPE_RESTRICT;
+ if (strstr((char*)ret_info, "pipe"))
+ type_qual = CL_KERNEL_ARG_TYPE_PIPE;
*(cl_kernel_arg_type_qualifier *)param_value = type_qual;
return CL_SUCCESS;
--
2.5.0
More information about the Beignet
mailing list