Add pipe builtin functions Signed-off-by: Pan Xiuli <xiuli....@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 f6176db..1c0cfae 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 93a2833..874206b 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"); @@ -1150,6 +1159,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)); @@ -1158,6 +1168,8 @@ namespace gbe if (!attrName) continue; if (attrName->getString() == "kernel_arg_type") { typeNameNode = attrNode; + } else if (attrName->getString() == "kernel_arg_type_qual") { + typeQualNode = attrNode; } } @@ -1165,9 +1177,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))); } } @@ -1262,6 +1276,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 @@ -2024,6 +2039,10 @@ namespace gbe (void)ctx.getFunction().getSamplerSet()->append(reg, &ctx); continue; } + if(llvmInfo.isPipeType()) { + ctx.input(argName, ir::FunctionArgument::PIPE, reg, llvmInfo, 4, 4, BtiMap.find(&*I)->second); + continue; + } if (type->isPointerTy() == false) ctx.input(argName, ir::FunctionArgument::VALUE, reg, llvmInfo, getTypeByteSize(unit, type), getAlignmentByte(unit, type), 0); @@ -3602,6 +3621,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: @@ -4412,6 +4449,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 0849f1e..a360d81 100644 --- a/backend/src/llvm/llvm_gen_ocl_function.hxx +++ b/backend/src/llvm/llvm_gen_ocl_function.hxx @@ -188,3 +188,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 9dc3fe6..b59d459 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 || !k->args[i].mem) + if ((arg_type != GBE_ARG_GLOBAL_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 _______________________________________________ Beignet mailing list Beignet@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/beignet