[Beignet] [PATCH 10/15] Backend: Implement StoreProfilingInstruction in GenContext.

junyan.he at inbox.com junyan.he at inbox.com
Wed Aug 12 01:49:26 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 |  156 +++++++++++++++++++++++++++++++++++
 1 file changed, 156 insertions(+)

diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 956b3db..c7cbf2d 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>
@@ -2352,8 +2353,163 @@ namespace gbe
   }
 
   void GenContext::emitStoreProfilingInstruction(const SelectionInstruction &insn) {
+    const GenRegister ptr = ra->genReg(insn.src(0));
+    uint32_t savedWidth = p->curr.execWidth;
+    GenRegister profilingReg[4];
+    if (p->curr.execWidth == 16) {
+      profilingReg[0] = GenRegister::retype(ra->genReg(insn.src(1)), GEN_TYPE_UD);
+      profilingReg[1] = GenRegister::offset(profilingReg[0], 1);
+      profilingReg[2] = GenRegister::retype(ra->genReg(insn.src(2)), GEN_TYPE_UD);
+      profilingReg[3] = GenRegister::offset(profilingReg[2], 1);
+    } else {
+      GBE_ASSERT(p->curr.execWidth == 8);
+      profilingReg[0] = GenRegister::retype(ra->genReg(insn.src(1)), GEN_TYPE_UD);
+      profilingReg[1] = GenRegister::retype(ra->genReg(insn.src(2)), GEN_TYPE_UD);
+      profilingReg[2] = GenRegister::retype(ra->genReg(insn.src(3)), GEN_TYPE_UD);
+      profilingReg[3] = GenRegister::retype(ra->genReg(insn.src(4)), GEN_TYPE_UD);
+    }
+    const GenRegister tmp0 = ra->genReg(insn.dst(0));
+    uint32_t profilingType = insn.extra.profilingType;
+    uint32_t bti = insn.extra.profilingBTI;
+    GBE_ASSERT(profilingType == 1);
+    GenRegister flagReg = GenRegister::flag(insn.state.flag, insn.state.subFlag);
+
+    // Inc the log items number.
+    p->push(); {
+      //ptr[0] is the total count of the log items.
+      GenRegister sndMsg = GenRegister::retype(tmp0, GEN_TYPE_UD);
+      sndMsg.width = GEN_WIDTH_8;
+      sndMsg.hstride = GEN_HORIZONTAL_STRIDE_1;
+      sndMsg.vstride = GEN_VERTICAL_STRIDE_8;
+      p->curr.execWidth = 8;
+      p->curr.predicate = GEN_PREDICATE_NONE;
+      p->curr.noMask = 1;
+      p->MOV(sndMsg, ptr);
+
+      GenRegister incRes = GenRegister::offset(sndMsg, 1);
+      p->push();
+      {
+        p->curr.execWidth = 1;
+        p->MOV(flagReg, GenRegister::immuw(0x01));
+      }
+      p->pop();
+      p->curr.useFlag(insn.state.flag, insn.state.subFlag);
+      p->curr.predicate = GEN_PREDICATE_NORMAL;
+      p->ATOMIC(incRes, GEN_ATOMIC_OP_INC, sndMsg, GenRegister::immud(bti), 1);
+    } p->pop();
 
+    // Calculate the final addr
+    GenRegister addr = GenRegister::retype(tmp0, GEN_TYPE_UD);
+    addr.width = GEN_WIDTH_8;
+    addr.hstride = GEN_HORIZONTAL_STRIDE_1;
+    addr.vstride = GEN_VERTICAL_STRIDE_8;
+    p->push(); {
+      GenRegister offset = GenRegister::offset(addr, 1);
+
+      p->curr.execWidth = 8;
+      p->curr.noMask = 1;
+      p->curr.predicate = GEN_PREDICATE_NONE;
+      p->MUL(addr, GenRegister::toUniform(offset, GEN_TYPE_UD),
+          GenRegister::immud(sizeof(ir::ProfilingInfo::ProfilingReportItem)));
+      p->ADD(addr, addr, ptr);
+      p->ADD(addr, addr, GenRegister::immud(4)); // for the counter
+      p->curr.execWidth = 1;
+      for (int i = 1; i < 8; i++) {
+        p->ADD(GenRegister::toUniform(GenRegister::offset(addr, 0, i*sizeof(uint32_t)), GEN_TYPE_UD),
+            GenRegister::toUniform(GenRegister::offset(addr, 0, i*sizeof(uint32_t)), GEN_TYPE_UD),
+            GenRegister::immud(i*sizeof(uint32_t)));
+      }
+    } p->pop();
+
+    // Write the result out
+    p->push(); {
+      GenRegister data = GenRegister::offset(addr, 1);
+      GenRegister ffid = GenRegister::toUniform(data, GEN_TYPE_UD);
+      GenRegister tmp = GenRegister::toUniform(GenRegister::offset(data, 0, 28), GEN_TYPE_UD);
+      GenRegister stateReg = GenRegister(GEN_ARCHITECTURE_REGISTER_FILE, GEN_ARF_STATE, 0,
+          GEN_TYPE_UD, GEN_VERTICAL_STRIDE_0, GEN_WIDTH_1, GEN_HORIZONTAL_STRIDE_1);
+      p->curr.predicate = GEN_PREDICATE_NONE;
+      p->curr.noMask = 1;
+      p->curr.execWidth = 1;
+      p->MOV(ffid, stateReg);
+      p->SHR(ffid, ffid, GenRegister::immud(24));
+      p->AND(ffid, ffid, GenRegister::immud(0x0ff));
+      p->OR(ffid, ffid, GenRegister::immud(ir::ProfilingInfo::ProfilingSimdType16 << 4));
+
+      GenRegister genInfo = GenRegister::offset(ffid, 0, 4);
+      p->MOV(genInfo, stateReg);
+      p->AND(genInfo, genInfo, GenRegister::immud(0x0ff07));
+      //The dispatch mask
+      stateReg = GenRegister(GEN_ARCHITECTURE_REGISTER_FILE, GEN_ARF_STATE, 2,
+          GEN_TYPE_UD, GEN_VERTICAL_STRIDE_0, GEN_WIDTH_1, GEN_HORIZONTAL_STRIDE_1);
+      p->MOV(tmp, stateReg);
+      p->AND(tmp, tmp, GenRegister::immud(0x0000ffff));
+      p->SHL(tmp, tmp, GenRegister::immud(16));
+      p->OR(genInfo, genInfo, tmp);
+
+      // X Y and Z
+#define CALC_GID(dim)  do {\
+  GenRegister g##dim##start = GenRegister::offset(genInfo, 0, 4 + dim*8); \
+  GenRegister g##dim##end = GenRegister::offset(g##dim##start, 0, 4);  \
+  GenRegister id##dim = GenRegister::toUniform(ra->genReg(GenRegister::ud16grf(ir::ocl::lid##dim)), GEN_TYPE_UD); \
+  GenRegister localsz##dim = GenRegister::toUniform(ra->genReg(GenRegister::ud1grf(ir::ocl::lsize##dim)), GEN_TYPE_UD); \
+  GenRegister gid##dim = GenRegister::toUniform(ra->genReg(GenRegister::ud1grf(ir::ocl::groupid##dim)), GEN_TYPE_UD); \
+  GenRegister goffset##dim = GenRegister::toUniform(ra->genReg(GenRegister::ud1grf(ir::ocl::goffset##dim)), GEN_TYPE_UD); \
+  p->MUL(g##dim##start, localsz##dim, gid##dim); \
+  p->ADD(g##dim##start, g##dim##start, id##dim); \
+  p->ADD(g##dim##start, g##dim##start, goffset##dim); \
+  GenRegister ip; \
+  p->curr.useFlag(insn.state.flag, insn.state.subFlag); \
+  p->curr.predicate = GEN_PREDICATE_NONE; \
+  if (savedWidth == 16) \
+  p->curr.execWidth = 16; \
+  else \
+  p->curr.execWidth = 8; \
+  if (!isDWLabel()) { \
+    ip = ra->genReg(GenRegister::uw16grf(ir::ocl::blockip)); \
+    p->CMP(GEN_CONDITIONAL_EQ, ip, GenRegister::immuw(0xffff)); \
+  } else { \
+    ip = ra->genReg(GenRegister::ud16grf(ir::ocl::dwblockip)); \
+    p->CMP(GEN_CONDITIONAL_EQ, ip, GenRegister::immud(0xffffffff)); \
+  } \
+  p->curr.execWidth = 1; \
+  p->MOV(GenRegister::retype(tmp, GEN_TYPE_UW), flagReg); \
+  if (savedWidth == 16) \
+  p->OR(tmp, tmp, GenRegister::immud(0xffff0000)); \
+  else \
+  p->OR(tmp, tmp, GenRegister::immud(0xffffff00)); \
+  p->FBL(tmp, tmp); \
+  p->ADD(tmp, tmp, GenRegister::negate(GenRegister::immud(0x1))); \
+  p->MUL(tmp, tmp, GenRegister::immud(4)); \
+  p->MOV(GenRegister::addr1(0), GenRegister::retype(tmp, GEN_TYPE_UW)); \
+  GenRegister dimEnd = GenRegister::to_indirect1xN(id##dim, 0); \
+  p->MOV(tmp, dimEnd); \
+  p->MUL(g##dim##end, localsz##dim, gid##dim); \
+  p->ADD(g##dim##end, g##dim##end, tmp); \
+  p->ADD(g##dim##end, g##dim##end, goffset##dim); \
+} while(0)
+
+      CALC_GID(0);
+      CALC_GID(1);
+      CALC_GID(2);
+#undef CALC_GID
+
+      // Write it out.
+      p->curr.execWidth = 8;
+      p->curr.noMask = 1;
+      p->UNTYPED_WRITE(addr, GenRegister::immud(bti), 1);
+      p->ADD(addr, addr, GenRegister::immud(32));
+
+      // time stamps
+      for (int i = 0; i < 3; i++) {
+        p->curr.execWidth = 8;
+        p->MOV(data, GenRegister::retype(profilingReg[i], GEN_TYPE_UD));
+        p->UNTYPED_WRITE(addr, GenRegister::immud(bti), 1);
+        p->ADD(addr, addr, GenRegister::immud(32));
+      }
+    } p->pop();
   }
+
   void GenContext::setA0Content(uint16_t new_a0[16], uint16_t max_offset, int sz) {
     if (sz == 0)
       sz = 8;
-- 
1.7.9.5



More information about the Beignet mailing list