[Beignet] [PATCH V3 1/2] add simd level function __gen_ocl_get_simd_size
Guo Yejun
yejun.guo at intel.com
Wed Apr 15 17:49:57 PDT 2015
uint __gen_ocl_get_simd_size();
returns 8 if SIMD8, returns 16 if SIMD16
V2: add missing files
remove unnecessary function
V3: correct the dst register setting, it is possible not uniform
Signed-off-by: Guo Yejun <yejun.guo at intel.com>
---
backend/src/backend/gen_insn_selection.cpp | 35 ++++++++++++++++++++++++++++++
backend/src/ir/context.hpp | 6 +++++
backend/src/ir/instruction.cpp | 30 +++++++++++++++++++++++++
backend/src/ir/instruction.hpp | 13 +++++++++++
backend/src/ir/instruction.hxx | 1 +
backend/src/libocl/CMakeLists.txt | 2 +-
backend/src/libocl/include/ocl.h | 1 +
backend/src/libocl/script/ocl_simd.def | 1 +
backend/src/libocl/tmpl/ocl_simd.tmpl.cl | 19 ++++++++++++++++
backend/src/libocl/tmpl/ocl_simd.tmpl.h | 27 +++++++++++++++++++++++
backend/src/llvm/llvm_gen_backend.cpp | 7 ++++++
backend/src/llvm/llvm_gen_ocl_function.hxx | 1 +
12 files changed, 142 insertions(+), 1 deletion(-)
create mode 100644 backend/src/libocl/script/ocl_simd.def
create mode 100644 backend/src/libocl/tmpl/ocl_simd.tmpl.cl
create mode 100644 backend/src/libocl/tmpl/ocl_simd.tmpl.h
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 3ac932b..a2a8468 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -622,6 +622,8 @@ namespace gbe
void MATH(Reg dst, uint32_t function, Reg src0, Reg src1);
/*! Extended math function (1 argument) */
void MATH(Reg dst, uint32_t function, Reg src);
+ /*! Encode nullary instructions */
+ void ALU0(SelectionOpcode opcode, Reg dst);
/*! Encode unary instructions */
void ALU1(SelectionOpcode opcode, Reg dst, Reg src);
/*! Encode unary with temp reg instructions */
@@ -2112,6 +2114,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 +4889,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 cf5109d..af65ff3 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 698e33e..86148bc 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 f9fdfd4..c603d9e 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 de4abfb..f86cfbb 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 at 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 6b825b0..0cd1eef 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 e886670..314bedd 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 0000000..8011546
--- /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 0000000..b9da5e2
--- /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 0000000..b992902
--- /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 9f4ed48..ac67add 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 9536a3c..2b151f2 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)
--
1.9.1
More information about the Beignet
mailing list