diff options
author | Guo Yejun <yejun.guo@intel.com> | 2015-04-16 10:50:49 +0800 |
---|---|---|
committer | Yang Rong <rong.r.yang@intel.com> | 2015-04-24 10:31:00 +0800 |
commit | e2019e40f0fe73acaa057689592accff9553e0be (patch) | |
tree | c7899046ce02eb10b2b2ed4bcb00c89e6386ed51 | |
parent | 7749e0d7e2f9316f26740a48df19e3103c893749 (diff) |
add simd level function __gen_ocl_get_simd_size
uint __gen_ocl_get_simd_size();
returns 8 if SIMD8, returns 16 if SIMD16
V2: add missing files
remove some unnecessary functions
V3: correct the dst register setting, it is possible not uniform
V4: remove unnecessary function
Signed-off-by: Guo Yejun <yejun.guo@intel.com>
Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
-rw-r--r-- | backend/src/backend/gen_insn_selection.cpp | 33 | ||||
-rw-r--r-- | backend/src/ir/context.hpp | 6 | ||||
-rw-r--r-- | backend/src/ir/instruction.cpp | 30 | ||||
-rw-r--r-- | backend/src/ir/instruction.hpp | 13 | ||||
-rw-r--r-- | backend/src/ir/instruction.hxx | 1 | ||||
-rw-r--r-- | backend/src/libocl/CMakeLists.txt | 2 | ||||
-rw-r--r-- | backend/src/libocl/include/ocl.h | 1 | ||||
-rw-r--r-- | backend/src/libocl/script/ocl_simd.def | 1 | ||||
-rw-r--r-- | backend/src/libocl/tmpl/ocl_simd.tmpl.cl | 19 | ||||
-rw-r--r-- | backend/src/libocl/tmpl/ocl_simd.tmpl.h | 27 | ||||
-rw-r--r-- | backend/src/llvm/llvm_gen_backend.cpp | 7 | ||||
-rw-r--r-- | backend/src/llvm/llvm_gen_ocl_function.hxx | 1 |
12 files changed, 140 insertions, 1 deletions
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp index 3ac932bb..026a858e 100644 --- a/backend/src/backend/gen_insn_selection.cpp +++ b/backend/src/backend/gen_insn_selection.cpp @@ -2112,6 +2112,38 @@ namespace gbe #define DECL_CTOR(FAMILY, INSN_NUM, COST) \ FAMILY##Pattern(void) : OneToManyPattern<FAMILY##Pattern, ir::FAMILY>(INSN_NUM, COST) {} + /*! Nullary instruction patterns */ + class NullaryInstructionPattern : public SelectionPattern + { + public: + NullaryInstructionPattern(void) : SelectionPattern(1,1) { + for (uint32_t op = 0; op < ir::OP_INVALID; ++op) + if (ir::isOpcodeFrom<ir::NullaryInstruction>(ir::Opcode(op)) == true) + this->opcodes.push_back(ir::Opcode(op)); + } + + INLINE bool emit(Selection::Opaque &sel, SelectionDAG &dag) const { + using namespace ir; + const ir::NullaryInstruction &insn = cast<NullaryInstruction>(dag.insn); + const Opcode opcode = insn.getOpcode(); + const Type type = insn.getType(); + GenRegister dst = sel.selReg(insn.getDst(0), type); + + sel.push(); + switch (opcode) { + case ir::OP_SIMD_SIZE: + { + const GenRegister src = GenRegister::immud(sel.curr.execWidth); + sel.MOV(dst, src); + } + break; + default: NOT_SUPPORTED; + } + sel.pop(); + return true; + } + }; + /*! Unary instruction patterns */ DECL_PATTERN(UnaryInstruction) { @@ -4855,6 +4887,7 @@ namespace gbe this->insert<GetImageInfoInstructionPattern>(); this->insert<ReadARFInstructionPattern>(); this->insert<RegionInstructionPattern>(); + this->insert<NullaryInstructionPattern>(); // Sort all the patterns with the number of instructions they output for (uint32_t op = 0; op < ir::OP_INVALID; ++op) diff --git a/backend/src/ir/context.hpp b/backend/src/ir/context.hpp index cf5109d0..af65ff32 100644 --- a/backend/src/ir/context.hpp +++ b/backend/src/ir/context.hpp @@ -176,6 +176,12 @@ namespace ir { DECL_THREE_SRC_INSN(MAD); #undef DECL_THREE_SRC_INSN + /*! For all nullary functions */ + void ALU0(Opcode opcode, Type type, Register dst) { + const Instruction insn = gbe::ir::ALU0(opcode, type, dst); + this->append(insn); + } + /*! For all unary functions */ void ALU1(Opcode opcode, Type type, Register dst, Register src) { const Instruction insn = gbe::ir::ALU1(opcode, type, dst, src); diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp index 698e33ee..86148bca 100644 --- a/backend/src/ir/instruction.cpp +++ b/backend/src/ir/instruction.cpp @@ -131,6 +131,17 @@ namespace ir { Register src[srcNum]; //!< Indices of the sources }; + /*! All 0-source arithmetic instructions */ + class ALIGNED_INSTRUCTION NullaryInstruction : public NaryInstruction<0> + { + public: + NullaryInstruction(Opcode opcode, Type type, Register dst) { + this->opcode = opcode; + this->type = type; + this->dst[0] = dst; + } + }; + /*! All 1-source arithmetic instructions */ class ALIGNED_INSTRUCTION UnaryInstruction : public NaryInstruction<1> { @@ -1306,6 +1317,10 @@ namespace ir { }; \ } +START_INTROSPECTION(NullaryInstruction) +#include "ir/instruction.hxx" +END_INTROSPECTION(NullaryInstruction) + START_INTROSPECTION(UnaryInstruction) #include "ir/instruction.hxx" END_INTROSPECTION(UnaryInstruction) @@ -1533,6 +1548,7 @@ END_FUNCTION(Instruction, Register) return reinterpret_cast<const internal::CLASS*>(this)->CALL; \ } +DECL_MEM_FN(NullaryInstruction, Type, getType(void), getType()) DECL_MEM_FN(UnaryInstruction, Type, getType(void), getType()) DECL_MEM_FN(BinaryInstruction, Type, getType(void), getType()) DECL_MEM_FN(BinaryInstruction, bool, commutes(void), commutes()) @@ -1586,6 +1602,20 @@ DECL_MEM_FN(GetImageInfoInstruction, uint8_t, getImageIndex(void), getImageIndex /////////////////////////////////////////////////////////////////////////// // Implements the emission functions /////////////////////////////////////////////////////////////////////////// + // For all nullary functions with given opcode + Instruction ALU0(Opcode opcode, Type type, Register dst) { + return internal::NullaryInstruction(opcode, type, dst).convert(); + } + + // All nullary functions +#define DECL_EMIT_FUNCTION(NAME) \ + Instruction NAME(Type type, Register dst) { \ + return ALU0(OP_##NAME, type, dst);\ + } + + DECL_EMIT_FUNCTION(SIMD_SIZE) + +#undef DECL_EMIT_FUNCTION // For all unary functions with given opcode Instruction ALU1(Opcode opcode, Type type, Register dst, Register src) { diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp index f9fdfd4a..c603d9e2 100644 --- a/backend/src/ir/instruction.hpp +++ b/backend/src/ir/instruction.hpp @@ -199,6 +199,15 @@ namespace ir { /*! Output the instruction string in the given stream */ std::ostream &operator<< (std::ostream &out, const Instruction &proxy); + /*! Nullary instruction instructions are typed. */ + class NullaryInstruction : public Instruction { + public: + /*! Get the type manipulated by the instruction */ + Type getType(void) const; + /*! Return true if the given instruction is an instance of this class */ + static bool isClassOf(const Instruction &insn); + }; + /*! Unary instructions are typed. dst and sources share the same type */ class UnaryInstruction : public Instruction { public: @@ -559,6 +568,10 @@ namespace ir { /// All emission functions /////////////////////////////////////////////////////////////////////////// + /*! alu0.type dst */ + Instruction ALU0(Opcode opcode, Type type, Register dst); + /*! simd_size.type dst */ + Instruction SIMD_SIZE(Type type, Register dst); /*! alu1.type dst src */ Instruction ALU1(Opcode opcode, Type type, Register dst, Register src); /*! mov.type dst src */ diff --git a/backend/src/ir/instruction.hxx b/backend/src/ir/instruction.hxx index de4abfb4..f86cfbb5 100644 --- a/backend/src/ir/instruction.hxx +++ b/backend/src/ir/instruction.hxx @@ -25,6 +25,7 @@ * \file instruction.hxx * \author Benjamin Segovia <benjamin.segovia@intel.com> */ +DECL_INSN(SIMD_SIZE, NullaryInstruction) DECL_INSN(MOV, UnaryInstruction) DECL_INSN(COS, UnaryInstruction) DECL_INSN(SIN, UnaryInstruction) diff --git a/backend/src/libocl/CMakeLists.txt b/backend/src/libocl/CMakeLists.txt index 6b825b04..0cd1eefd 100644 --- a/backend/src/libocl/CMakeLists.txt +++ b/backend/src/libocl/CMakeLists.txt @@ -90,7 +90,7 @@ MACRO(GENERATE_SOURCE_PY _mod) ) ENDMACRO(GENERATE_SOURCE_PY) -SET (OCL_PY_GENERATED_MODULES ocl_common ocl_relational ocl_integer ocl_math) +SET (OCL_PY_GENERATED_MODULES ocl_common ocl_relational ocl_integer ocl_math ocl_simd) FOREACH(M ${OCL_PY_GENERATED_MODULES}) GENERATE_HEADER_PY(${M}) GENERATE_SOURCE_PY(${M}) diff --git a/backend/src/libocl/include/ocl.h b/backend/src/libocl/include/ocl.h index e8866702..314bedd3 100644 --- a/backend/src/libocl/include/ocl.h +++ b/backend/src/libocl/include/ocl.h @@ -36,6 +36,7 @@ #include "ocl_sync.h" #include "ocl_vload.h" #include "ocl_workitem.h" +#include "ocl_simd.h" #pragma OPENCL EXTENSION cl_khr_fp64 : disable #endif diff --git a/backend/src/libocl/script/ocl_simd.def b/backend/src/libocl/script/ocl_simd.def new file mode 100644 index 00000000..80115462 --- /dev/null +++ b/backend/src/libocl/script/ocl_simd.def @@ -0,0 +1 @@ +##simd level functions diff --git a/backend/src/libocl/tmpl/ocl_simd.tmpl.cl b/backend/src/libocl/tmpl/ocl_simd.tmpl.cl new file mode 100644 index 00000000..b9da5e29 --- /dev/null +++ b/backend/src/libocl/tmpl/ocl_simd.tmpl.cl @@ -0,0 +1,19 @@ +/* + * Copyright @ 2015 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_simd.h" diff --git a/backend/src/libocl/tmpl/ocl_simd.tmpl.h b/backend/src/libocl/tmpl/ocl_simd.tmpl.h new file mode 100644 index 00000000..b9929022 --- /dev/null +++ b/backend/src/libocl/tmpl/ocl_simd.tmpl.h @@ -0,0 +1,27 @@ +/* + * Copyright © 2015 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_SIMD_H__ +#define __OCL_SIMD_H__ + +#include "ocl_types.h" + +///////////////////////////////////////////////////////////////////////////// +// SIMD level function +///////////////////////////////////////////////////////////////////////////// + +uint __gen_ocl_get_simd_size(void); diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp index 9f4ed48c..ac67add5 100644 --- a/backend/src/llvm/llvm_gen_backend.cpp +++ b/backend/src/llvm/llvm_gen_backend.cpp @@ -2803,6 +2803,7 @@ namespace gbe case GEN_OCL_CONV_F32_TO_F16: case GEN_OCL_SIMD_ANY: case GEN_OCL_SIMD_ALL: + case GEN_OCL_SIMD_SIZE: case GEN_OCL_READ_TM: case GEN_OCL_REGION: this->newRegister(&I); @@ -3454,6 +3455,12 @@ namespace gbe assert(fmt); break; } + case GEN_OCL_SIMD_SIZE: + { + const ir::Register dst = this->getRegister(&I); + ctx.ALU0(ir::OP_SIMD_SIZE, getType(ctx, I.getType()), dst); + break; + } default: break; } } diff --git a/backend/src/llvm/llvm_gen_ocl_function.hxx b/backend/src/llvm/llvm_gen_ocl_function.hxx index 9536a3c4..2b151f28 100644 --- a/backend/src/llvm/llvm_gen_ocl_function.hxx +++ b/backend/src/llvm/llvm_gen_ocl_function.hxx @@ -154,6 +154,7 @@ DECL_LLVM_GEN_FUNCTION(CONV_F32_TO_F16, __gen_ocl_f32to16) // SIMD level function for internal usage DECL_LLVM_GEN_FUNCTION(SIMD_ANY, __gen_ocl_simd_any) DECL_LLVM_GEN_FUNCTION(SIMD_ALL, __gen_ocl_simd_all) +DECL_LLVM_GEN_FUNCTION(SIMD_SIZE, __gen_ocl_get_simd_size) DECL_LLVM_GEN_FUNCTION(READ_TM, __gen_ocl_read_tm) DECL_LLVM_GEN_FUNCTION(REGION, __gen_ocl_region) |