[Beignet] [PATCH 1/2] add simd level function __gen_ocl_get_simd_size

Guo Yejun yejun.guo at intel.com
Tue Apr 14 01:07:09 PDT 2015


uint __gen_ocl_get_simd_size();
returns 8 if SIMD8, returns 16 if SIMD16

Signed-off-by: Guo Yejun <yejun.guo at intel.com>
---
 backend/src/backend/gen_insn_selection.cpp | 41 ++++++++++++++++++++++++++++++
 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/include/ocl.h           |  1 +
 backend/src/llvm/llvm_gen_backend.cpp      |  9 +++++++
 backend/src/llvm/llvm_gen_ocl_function.hxx |  1 +
 8 files changed, 102 insertions(+)

diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 3ac932b..2ee148b 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 */
@@ -1493,6 +1495,11 @@ namespace gbe
       insn->dst(i + 1) = tmp[i];
   }
 
+  void Selection::Opaque::ALU0(SelectionOpcode opcode, Reg dst) {
+    SelectionInstruction *insn = this->appendInsn(opcode, 1, 0);
+    insn->dst(0) = dst;
+  }
+
   void Selection::Opaque::ALU1(SelectionOpcode opcode, Reg dst, Reg src) {
     SelectionInstruction *insn = this->appendInsn(opcode, 1, 1);
     insn->dst(0) = dst;
@@ -2112,6 +2119,39 @@ 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.curr.execWidth = 1;
+            sel.MOV(dst, src);
+          }
+          break;
+        default: NOT_SUPPORTED;
+      }
+      sel.pop();
+      return true;
+    }
+  };
+
   /*! Unary instruction patterns */
   DECL_PATTERN(UnaryInstruction)
   {
@@ -4855,6 +4895,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/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/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 9f4ed48..18803b7 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -2807,6 +2807,9 @@ namespace gbe
       case GEN_OCL_REGION:
         this->newRegister(&I);
         break;
+      case GEN_OCL_SIMD_SIZE:
+        this->newRegister(&I, NULL, true);
+        break;
       case GEN_OCL_PRINTF:
         break;
       case GEN_OCL_NOT_FOUND:
@@ -3454,6 +3457,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