[Beignet] [Printf v2][PATCH 08/12] Implement instruction selection of printf.

yan.wang at linux.intel.com yan.wang at linux.intel.com
Sun Jan 31 23:42:26 PST 2016


From: Yan Wang <yan.wang at linux.intel.com>

Contributor: Junyan He <junyan.he at linux.intel.com>
Signed-off-by: Yan Wang <yan.wang at linux.intel.com>
---
 backend/src/backend/gen_context.cpp                |   3 +
 backend/src/backend/gen_context.hpp                |   1 +
 .../src/backend/gen_insn_gen7_schedule_info.hxx    |   3 +-
 backend/src/backend/gen_insn_selection.cpp         | 116 +++++++++++++++++++++
 backend/src/backend/gen_insn_selection.hpp         |   6 ++
 backend/src/backend/gen_insn_selection.hxx         |   1 +
 6 files changed, 129 insertions(+), 1 deletion(-)

diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 0ea0dd0..7807289 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -3148,6 +3148,9 @@ do { \
       p->patchJMPI(oneThreadJip, (p->n_instruction() - oneThreadJip), 0);
   }
 
+  void GenContext::emitPrintfInstruction(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 22ec0ea..036fa78 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -180,6 +180,7 @@ namespace gbe
     void emitCalcTimestampInstruction(const SelectionInstruction &insn);
     void emitStoreProfilingInstruction(const SelectionInstruction &insn);
     void emitWorkGroupOpInstruction(const SelectionInstruction &insn);
+    void emitPrintfInstruction(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, GenRegister btiTmp, 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 8ef422f..112df32 100644
--- a/backend/src/backend/gen_insn_gen7_schedule_info.hxx
+++ b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
@@ -47,4 +47,5 @@ DECL_GEN7_SCHEDULE(I64SATSUB,       20,        40,      20)
 DECL_GEN7_SCHEDULE(F64DIV,          20,        40,      20)
 DECL_GEN7_SCHEDULE(CalcTimestamp,   80,        1,        1)
 DECL_GEN7_SCHEDULE(StoreProfiling,  80,        1,        1)
-DECL_GEN7_SCHEDULE(WorkGroupOp, 	80, 		1,		 1)
+DECL_GEN7_SCHEDULE(WorkGroupOp,     80,        1,        1)
+DECL_GEN7_SCHEDULE(Printf,          80,        1,        1)
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 001a3c5..6eecde2 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -676,6 +676,9 @@ namespace gbe
     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);
+    /*! Printf */
+    void PRINTF(GenRegister dst, uint8_t bti, GenRegister tmp0, GenRegister tmp1, GenRegister src[8],
+                int srcNum, uint16_t num, bool isContinue, uint32_t totalSize);
     /*! Multiply 64-bit integers */
     void I64MUL(Reg dst, Reg src0, Reg src1, GenRegister *tmp, bool native_long);
     /*! 64-bit integer division */
@@ -1905,6 +1908,53 @@ namespace gbe
     }
   }
 
+  void Selection::Opaque::PRINTF(GenRegister dst, uint8_t bti, GenRegister tmp0, GenRegister tmp1,
+               GenRegister src[8], int srcNum, uint16_t num, bool isContinue, uint32_t totalSize) {
+    if (isContinue) {
+      SelectionInstruction *insn = this->appendInsn(SEL_OP_PRINTF, 3, srcNum + 1);
+      SelectionVector *vector = this->appendVector();
+
+      for (int i = 0; i < srcNum; i++)
+        insn->src(i) = src[i];
+
+      insn->src(srcNum) = tmp0;
+
+      insn->dst(0) = dst;
+      insn->dst(1) = tmp0;
+      insn->dst(2) = tmp1;
+
+      vector->regNum = 2;
+      vector->reg = &insn->dst(1);
+      vector->offsetID = 0;
+      vector->isSrc = 0;
+
+      insn->extra.printfSize = static_cast<uint16_t>(totalSize);
+      insn->extra.continueFlag = isContinue;
+      insn->extra.printfBTI = bti;
+      insn->extra.printfNum = num;
+    } else {
+      SelectionInstruction *insn = this->appendInsn(SEL_OP_PRINTF, 3, srcNum);
+      SelectionVector *vector = this->appendVector();
+
+      for (int i = 0; i < srcNum; i++)
+        insn->src(i) = src[i];
+
+      insn->dst(0) = dst;
+      insn->dst(1) = tmp0;
+      insn->dst(2) = tmp1;
+
+      vector->regNum = 2;
+      vector->reg = &insn->dst(1);
+      vector->offsetID = 0;
+      vector->isSrc = 0;
+
+      insn->extra.printfSize = static_cast<uint16_t>(totalSize);
+      insn->extra.continueFlag = isContinue;
+      insn->extra.printfBTI = bti;
+      insn->extra.printfNum = num;
+    }
+  }
+
   void Selection::Opaque::WORKGROUP_OP(uint32_t wg_op, Reg dst, GenRegister src, GenRegister nextThreadID,
                       GenRegister threadID, GenRegister threadn, GenRegister tmp) {
     SelectionInstruction *insn = this->appendInsn(SEL_OP_WORKGROUP_OP, 3, 4);
@@ -5820,6 +5870,71 @@ extern bool OCL_DEBUGINFO; // first defined by calling BVAR in program.cpp
     }
   };
 
+  class PrintfInstructionPattern : public SelectionPattern
+  {
+  public:
+    PrintfInstructionPattern(void) : SelectionPattern(1,1) {
+      this->opcodes.push_back(ir::OP_PRINTF);
+    }
+    INLINE bool emit(Selection::Opaque &sel, SelectionDAG &dag) const {
+      using namespace ir;
+      const ir::PrintfInstruction &insn = cast<ir::PrintfInstruction>(dag.insn);
+      uint16_t num = insn.getNum();
+      uint8_t BTI = insn.getBti();
+      GenRegister tmp0, tmp1;
+      uint32_t srcNum = insn.getSrcNum();
+      GenRegister dst = sel.selReg(insn.getDst(0), TYPE_S32);
+      //GBE_ASSERT(srcNum);
+      uint32_t i = 0;
+      uint32_t totalSize = 0;
+      bool isContinue = false;
+      GBE_ASSERT(sel.ctx.getSimdWidth() == 16 || sel.ctx.getSimdWidth() == 8);
+      if (sel.ctx.getSimdWidth() == 16) {
+        tmp0 = GenRegister::retype(sel.selReg(sel.reg(FAMILY_DWORD)), GEN_TYPE_UD);
+        tmp1 = GenRegister::retype(sel.selReg(sel.reg(FAMILY_DWORD)), GEN_TYPE_UD);
+      } else {
+        tmp0 = GenRegister::retype(sel.selReg(sel.reg(FAMILY_QWORD)), GEN_TYPE_UD);
+        tmp1 = GenRegister::retype(sel.selReg(sel.reg(FAMILY_QWORD)), GEN_TYPE_UD);
+      }
+
+      /* Get the total size for one printf statement. */
+      for (i = 0; i < srcNum; i++) {
+        Type type = insn.getType(i);
+        if (type == TYPE_DOUBLE || type == TYPE_S64 || type == TYPE_U64) {
+          totalSize += 8;
+        } else {
+          totalSize += 4; // Make sure always align to 4.
+        }
+      }
+
+      i = 0;
+      GenRegister regs[8];
+      if (srcNum == 0) {
+          sel.PRINTF(dst, BTI, tmp0, tmp1, regs, srcNum, num, isContinue, totalSize);
+      } else {
+        do {
+          uint32_t s = srcNum < 8 ? srcNum : 8;
+          for (uint32_t j = 0; j < s; j++) {
+            regs[j] = sel.selReg(insn.getSrc(i + j), insn.getType(i + j));
+          }
+          sel.PRINTF(dst, BTI, tmp0, tmp1, regs, s, num, isContinue, totalSize);
+
+          if (srcNum > 8) {
+            srcNum -= 8;
+            i += 8;
+          } else {
+            srcNum = 0;
+          }
+
+          isContinue = true;
+        } while(srcNum);
+      }
+
+      markAllChildren(dag);
+      return true;
+    }
+  };
+
   /*! Branch instruction pattern */
   class BranchInstructionPattern : public SelectionPattern
   {
@@ -6271,6 +6386,7 @@ extern bool OCL_DEBUGINFO; // first defined by calling BVAR in program.cpp
     this->insert<WorkGroupInstructionPattern>();
     this->insert<NullaryInstructionPattern>();
     this->insert<WaitInstructionPattern>();
+    this->insert<PrintfInstructionPattern>();
 
     // 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/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index 3889ef2..8d2e1da 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -149,6 +149,12 @@ namespace gbe
         uint32_t profilingType:16;
         uint32_t profilingBTI:16;
       };
+      struct {
+        uint32_t printfNum:16;
+        uint32_t printfBTI:8;
+        uint32_t continueFlag:8;
+        uint16_t printfSize;
+      };
       uint32_t workgroupOp;
     } extra;
     /*! Gen opcode */
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index 597e042..4352490 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -94,3 +94,4 @@ DECL_SELECTION_IR(F64DIV, F64DIVInstruction)
 DECL_SELECTION_IR(CALC_TIMESTAMP, CalcTimestampInstruction)
 DECL_SELECTION_IR(STORE_PROFILING, StoreProfilingInstruction)
 DECL_SELECTION_IR(WORKGROUP_OP, WorkGroupOpInstruction)
+DECL_SELECTION_IR(PRINTF, PrintfInstruction)
-- 
2.4.3



More information about the Beignet mailing list