[Beignet] [PATCH 09/19] Backend: Add CalcTimestamp and StoreProfiling to insn selection.

junyan.he at inbox.com junyan.he at inbox.com
Tue Sep 8 17:01:00 PDT 2015


From: Junyan He <junyan.he at linux.intel.com>

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/backend/gen_context.cpp                |    9 ++
 backend/src/backend/gen_context.hpp                |    2 +
 .../src/backend/gen_insn_gen7_schedule_info.hxx    |    2 +
 backend/src/backend/gen_insn_selection.cpp         |  140 ++++++++++++++++++++
 backend/src/backend/gen_insn_selection.hpp         |    8 ++
 backend/src/backend/gen_insn_selection.hxx         |    2 +
 6 files changed, 163 insertions(+)

diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 25fdf08..435b224 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -32,6 +32,7 @@
 #include "backend/gen/gen_mesa_disasm.h"
 #include "ir/function.hpp"
 #include "ir/value.hpp"
+#include "ir/profiling.hpp"
 #include "sys/cvar.hpp"
 #include <cstring>
 #include <iostream>
@@ -52,6 +53,7 @@ namespace gbe
     this->asmFileName = NULL;
     this->ifEndifFix = false;
     this->regSpillTick = 0;
+    this->inProfilingMode = false;
   }
 
   GenContext::~GenContext(void) {
@@ -2183,6 +2185,13 @@ namespace gbe
     p->TYPED_WRITE(header, true, bti);
   }
 
+  void GenContext::emitCalcTimestampInstruction(const SelectionInstruction &insn) {
+
+  }
+
+  void GenContext::emitStoreProfilingInstruction(const SelectionInstruction &insn) {
+  }
+
   void GenContext::setA0Content(uint16_t new_a0[16], uint16_t max_offset, int sz) {
     if (sz == 0)
       sz = 8;
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index 8c7b821..bbd48cf 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -173,6 +173,8 @@ namespace gbe
     void emitGetImageInfoInstruction(const SelectionInstruction &insn);
     virtual void emitI64MULInstruction(const SelectionInstruction &insn);
     virtual void emitI64DIVREMInstruction(const SelectionInstruction &insn);
+    void emitCalcTimestampInstruction(const SelectionInstruction &insn);
+    void emitStoreProfilingInstruction(const SelectionInstruction &insn);
     void scratchWrite(const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type, uint32_t channel_mode);
     void scratchRead(const GenRegister dst, const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type, uint32_t channel_mode);
     unsigned beforeMessage(const SelectionInstruction &insn, GenRegister bti, GenRegister flagTemp, unsigned desc);
diff --git a/backend/src/backend/gen_insn_gen7_schedule_info.hxx b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
index d073770..9022d5d 100644
--- a/backend/src/backend/gen_insn_gen7_schedule_info.hxx
+++ b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
@@ -43,3 +43,5 @@ DECL_GEN7_SCHEDULE(Atomic,          80,        1,        1)
 DECL_GEN7_SCHEDULE(I64MUL,          20,        40,      20)
 DECL_GEN7_SCHEDULE(I64SATADD,       20,        40,      20)
 DECL_GEN7_SCHEDULE(I64SATSUB,       20,        40,      20)
+DECL_GEN7_SCHEDULE(CalcTimestamp,   80,        1,        1)
+DECL_GEN7_SCHEDULE(StoreProfiling,   80,        1,        1)
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index ab00269..e9a4b61 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -663,6 +663,10 @@ namespace gbe
     void TYPED_WRITE(GenRegister *msgs, uint32_t msgNum, uint32_t bti, bool is3D);
     /*! Get image information */
     void GET_IMAGE_INFO(uint32_t type, GenRegister *dst, uint32_t dst_num, uint32_t bti);
+    /*! Calculate the timestamp */
+    void CALC_TIMESTAMP(GenRegister ts[4], int tsN, GenRegister tmp, uint32_t pointNum, uint32_t tsType);
+    /*! Store the profiling info */
+    void STORE_PROFILING(uint32_t profilingType, uint32_t bti, GenRegister tmp0, GenRegister tmp1, GenRegister ts[4], int tsNum);
     /*! Multiply 64-bit integers */
     void I64MUL(Reg dst, Reg src0, Reg src1, GenRegister *tmp, bool native_long);
     /*! 64-bit integer division */
@@ -1774,6 +1778,55 @@ namespace gbe
       insn->dst(i + 1) = tmp[i];
   }
 
+  void Selection::Opaque::CALC_TIMESTAMP(GenRegister ts[4], int tsN, GenRegister tmp, uint32_t pointNum, uint32_t tsType) {
+    SelectionInstruction *insn = NULL;
+    if (!this->hasLongType()) {
+      insn = this->appendInsn(SEL_OP_CALC_TIMESTAMP, tsN + 1, tsN);
+    } else {// No need for tmp
+      insn = this->appendInsn(SEL_OP_CALC_TIMESTAMP, tsN, tsN);
+    }
+
+    for (int i = 0; i < tsN; i++) {
+      insn->src(i) = ts[i];
+      insn->dst(i) = ts[i];
+    }
+
+    if (!this->hasLongType())
+      insn->dst(tsN) = tmp;
+
+    insn->extra.pointNum = static_cast<uint16_t>(pointNum);
+    insn->extra.timestampType = static_cast<uint16_t>(tsType);
+  }
+
+  void Selection::Opaque::STORE_PROFILING(uint32_t profilingType, uint32_t bti,
+                GenRegister tmp0, GenRegister tmp1, GenRegister ts[4], int tsNum) {
+    if (tsNum == 3) { // SIMD16 mode
+      SelectionInstruction *insn = this->appendInsn(SEL_OP_STORE_PROFILING, 1, 3);
+      for (int i = 0; i < 3; i++)
+        insn->src(i) = ts[i];
+      insn->dst(0) = tmp0;
+
+      insn->extra.profilingType = static_cast<uint16_t>(profilingType);
+      insn->extra.profilingBTI = static_cast<uint16_t>(bti);
+    } else { // SIMD8 mode
+      GBE_ASSERT(tsNum == 5);
+      SelectionInstruction *insn = this->appendInsn(SEL_OP_STORE_PROFILING, 2, 5);
+      SelectionVector *dstVector = this->appendVector();
+      for (int i = 0; i < 5; i++)
+        insn->src(i) = ts[i];
+      insn->dst(0) = tmp0;
+      insn->dst(1) = tmp1;
+
+      dstVector->regNum = 2;
+      dstVector->isSrc = 0;
+      dstVector->offsetID = 0;
+      dstVector->reg = &insn->dst(0);
+
+      insn->extra.profilingType = static_cast<uint16_t>(profilingType);
+      insn->extra.profilingBTI = static_cast<uint16_t>(bti);
+    }
+  }
+
   // Boiler plate to initialize the selection library at c++ pre-main
   static SelectionLibrary *selLib = NULL;
   static void destroySelectionLibrary(void) { GBE_DELETE(selLib); }
@@ -5094,6 +5147,91 @@ namespace gbe
     }
   };
 
+  class CalcTimestampInstructionPattern : public SelectionPattern
+  {
+  public:
+    CalcTimestampInstructionPattern(void) : SelectionPattern(1,1) {
+      this->opcodes.push_back(ir::OP_CALC_TIMESTAMP);
+    }
+    INLINE bool emit(Selection::Opaque &sel, SelectionDAG &dag) const {
+      using namespace ir;
+      const ir::CalcTimestampInstruction &insn = cast<ir::CalcTimestampInstruction>(dag.insn);
+      uint32_t pointNum = insn.getPointNum();
+      uint32_t tsType = insn.getTimestamptType();
+      GBE_ASSERT(sel.ctx.getSimdWidth() == 16 || sel.ctx.getSimdWidth() == 8);
+      GenRegister tmp;
+      GenRegister ts[5];
+      int tsNum;
+      if (sel.ctx.getSimdWidth() == 16) {
+        if (!sel.hasLongType())
+          tmp = GenRegister::retype(sel.selReg(sel.reg(FAMILY_WORD)), GEN_TYPE_UD);
+        ts[0] = GenRegister::retype(sel.selReg(ir::ocl::profilingts0, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[1] = GenRegister::retype(sel.selReg(ir::ocl::profilingts1, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[2] = GenRegister::retype(sel.selReg(ir::ocl::profilingts2, ir::TYPE_U32), GEN_TYPE_UW);
+        tsNum = 3;
+      } else {
+        if (!sel.hasLongType())
+          tmp = GenRegister::retype(sel.selReg(sel.reg(FAMILY_DWORD)), GEN_TYPE_UD);
+        ts[0] = GenRegister::retype(sel.selReg(ir::ocl::profilingts0, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[1] = GenRegister::retype(sel.selReg(ir::ocl::profilingts1, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[2] = GenRegister::retype(sel.selReg(ir::ocl::profilingts2, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[3] = GenRegister::retype(sel.selReg(ir::ocl::profilingts3, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[4] = GenRegister::retype(sel.selReg(ir::ocl::profilingts4, ir::TYPE_U32), GEN_TYPE_UD);
+        tsNum = 5;
+      }
+
+      sel.push(); {
+        sel.curr.flag = 0;
+        sel.curr.subFlag = 1;
+        sel.CALC_TIMESTAMP(ts, tsNum, tmp, pointNum, tsType);
+      } sel.pop();
+      markAllChildren(dag);
+      return true;
+    }
+  };
+
+  class StoreProfilingInstructionPattern : public SelectionPattern
+  {
+  public:
+    StoreProfilingInstructionPattern(void) : SelectionPattern(1,1) {
+      this->opcodes.push_back(ir::OP_STORE_PROFILING);
+    }
+    INLINE bool emit(Selection::Opaque &sel, SelectionDAG &dag) const {
+      using namespace ir;
+      const ir::StoreProfilingInstruction &insn = cast<ir::StoreProfilingInstruction>(dag.insn);
+      uint32_t profilingType = insn.getProfilingType();
+      uint32_t BTI = insn.getBTI();
+      GBE_ASSERT(sel.ctx.getSimdWidth() == 16 || sel.ctx.getSimdWidth() == 8);
+      GenRegister tmp0;
+      GenRegister tmp1;
+      GenRegister ts[5];
+      int tsNum;
+      if (sel.ctx.getSimdWidth() == 16) {
+        tmp0 = GenRegister::retype(sel.selReg(sel.reg(FAMILY_DWORD)), GEN_TYPE_UD);
+        ts[0] = GenRegister::retype(sel.selReg(ir::ocl::profilingts0, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[1] = GenRegister::retype(sel.selReg(ir::ocl::profilingts1, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[2] = GenRegister::retype(sel.selReg(ir::ocl::profilingts2, ir::TYPE_U32), GEN_TYPE_UW);
+        tsNum = 3;
+      } else {
+        tmp0 = GenRegister::retype(sel.selReg(sel.reg(FAMILY_DWORD)), GEN_TYPE_UD);
+        tmp1 = GenRegister::retype(sel.selReg(sel.reg(FAMILY_DWORD)), GEN_TYPE_UD);
+        ts[0] = GenRegister::retype(sel.selReg(ir::ocl::profilingts0, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[1] = GenRegister::retype(sel.selReg(ir::ocl::profilingts1, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[2] = GenRegister::retype(sel.selReg(ir::ocl::profilingts2, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[3] = GenRegister::retype(sel.selReg(ir::ocl::profilingts3, ir::TYPE_U32), GEN_TYPE_UD);
+        ts[4] = GenRegister::retype(sel.selReg(ir::ocl::profilingts4, ir::TYPE_U32), GEN_TYPE_UD);
+        tsNum = 5;
+      }
+      sel.push(); {
+        sel.curr.flag = 0;
+        sel.curr.subFlag = 1;
+        sel.STORE_PROFILING(profilingType, BTI, tmp0, tmp1, ts, tsNum);
+      } sel.pop();
+      markAllChildren(dag);
+      return true;
+    }
+  };
+
   /*! Branch instruction pattern */
   class BranchInstructionPattern : public SelectionPattern
   {
@@ -5322,6 +5460,8 @@ namespace gbe
     this->insert<RegionInstructionPattern>();
     this->insert<SimdShuffleInstructionPattern>();
     this->insert<IndirectMovInstructionPattern>();
+    this->insert<CalcTimestampInstructionPattern>();
+    this->insert<StoreProfilingInstructionPattern>();
     this->insert<NullaryInstructionPattern>();
 
     // Sort all the patterns with the number of instructions they output
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index ffc79e1..c779ef1 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -132,6 +132,14 @@ namespace gbe
       uint32_t barrierType;
       bool longjmp;
       uint32_t indirect_offset;
+      struct {
+        uint32_t pointNum:16;
+        uint32_t timestampType:16;
+      };
+      struct {
+        uint32_t profilingType:16;
+        uint32_t profilingBTI:16;
+      };
     } extra;
     /*! Gen opcode */
     uint8_t opcode;
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index adbb137..90fb130 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -90,3 +90,5 @@ DECL_SELECTION_IR(ENDIF, UnaryInstruction)
 DECL_SELECTION_IR(ELSE, UnaryInstruction)
 DECL_SELECTION_IR(READ_ARF, UnaryInstruction)
 DECL_SELECTION_IR(WHILE, UnaryInstruction)
+DECL_SELECTION_IR(CALC_TIMESTAMP, CalcTimestampInstruction)
+DECL_SELECTION_IR(STORE_PROFILING, StoreProfilingInstruction)
-- 
1.7.9.5





More information about the Beignet mailing list