[Beignet] [PATCH V2] add sends support for oword/media block write

Pan, Xiuli xiuli.pan at intel.com
Wed Dec 28 07:48:06 UTC 2016


LGTM!
Thanks

-----Original Message-----
From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of Guo, Yejun
Sent: Wednesday, December 28, 2016 3:18 PM
To: beignet at lists.freedesktop.org
Cc: Guo, Yejun <yejun.guo at intel.com>
Subject: [Beignet] [PATCH V2] add sends support for oword/media block write

v2: should also change the virtual function prototype for gen7
Signed-off-by: Guo, Yejun <yejun.guo at intel.com>
---
 backend/src/backend/gen7_encoder.cpp       |  2 +-
 backend/src/backend/gen7_encoder.hpp       |  2 +-
 backend/src/backend/gen9_encoder.cpp       | 57 ++++++++++++++++++++++++++++++
 backend/src/backend/gen9_encoder.hpp       |  2 ++
 backend/src/backend/gen_context.cpp        |  6 ++--
 backend/src/backend/gen_encoder.cpp        |  4 +--
 backend/src/backend/gen_encoder.hpp        |  4 +--
 backend/src/backend/gen_insn_selection.cpp | 54 +++++++++++++++++++++-------
 8 files changed, 111 insertions(+), 20 deletions(-)

diff --git a/backend/src/backend/gen7_encoder.cpp b/backend/src/backend/gen7_encoder.cpp
index 4f35491..4b2cd9a 100644
--- a/backend/src/backend/gen7_encoder.cpp
+++ b/backend/src/backend/gen7_encoder.cpp
@@ -280,7 +280,7 @@ namespace gbe
                 response_length);
   }
 
-  void Gen7Encoder::MBWRITE(GenRegister header, uint32_t bti, uint32_t size) {
+  void Gen7Encoder::MBWRITE(GenRegister header, GenRegister data, 
+ uint32_t bti, uint32_t size, bool useSends) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
     const uint32_t msg_length = 1 + size;
     const uint32_t response_length = 0; // Size of registers diff --git a/backend/src/backend/gen7_encoder.hpp b/backend/src/backend/gen7_encoder.hpp
index edb711d..7585b34 100644
--- a/backend/src/backend/gen7_encoder.hpp
+++ b/backend/src/backend/gen7_encoder.hpp
@@ -45,7 +45,7 @@ namespace gbe
     /*! MBlock read */
     virtual void MBREAD(GenRegister dst, GenRegister header, uint32_t bti, uint32_t elemSize);
     /*! MBlock write */
-    virtual void MBWRITE(GenRegister header, uint32_t bti, uint32_t elemSize);
+    virtual void MBWRITE(GenRegister header, GenRegister data, uint32_t 
+ bti, uint32_t elemSize, bool useSends);
   };
 }
 #endif /* __GBE_GEN7_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen9_encoder.cpp b/backend/src/backend/gen9_encoder.cpp
index 940809b..b37fd98 100644
--- a/backend/src/backend/gen9_encoder.cpp
+++ b/backend/src/backend/gen9_encoder.cpp
@@ -244,4 +244,61 @@ namespace gbe
         gen9_insn->bits2.sends.sel_reg32_desc = 1;
     }
   }
+
+  void Gen9Encoder::OBWRITE(GenRegister header, GenRegister data, 
+ uint32_t bti, uint32_t ow_size, bool useSends)  {
+    if (!useSends)
+      Gen8Encoder::OBWRITE(header, data, bti, ow_size, false);
+    else {
+      GBE_ASSERT(data.reg() != header.reg());
+      GenNativeInstruction *insn = this->next(GEN_OPCODE_SENDS);
+      Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+
+      this->setHeader(insn);
+      insn->header.destreg_or_condmod = GEN_SFID_DATAPORT_DATA;
+
+      setSendsOperands(gen9_insn, GenRegister::null(), header, data);
+
+      uint32_t dataRegs = ow_size / 2;
+      // half reg should also have size 1
+      if (dataRegs == 0)
+        dataRegs = 1;
+      gen9_insn->bits2.sends.src1_length = dataRegs;
+
+      const uint32_t block_size = getOBlockSize(ow_size);
+      const uint32_t msg_length = 1;
+      const uint32_t response_length = 0;
+      setOBlockRW(insn,
+                bti,
+                block_size,
+                GEN7_OBLOCK_WRITE,
+                msg_length,
+                response_length);
+    }
+  }
+
+  void Gen9Encoder::MBWRITE(GenRegister header, GenRegister data, 
+ uint32_t bti, uint32_t data_size, bool useSends)  {
+    if (!useSends)
+      Gen8Encoder::MBWRITE(header, data, bti, data_size, false);
+    else {
+      GBE_ASSERT(data.reg() != header.reg());
+      GenNativeInstruction *insn = this->next(GEN_OPCODE_SENDS);
+      Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+
+      this->setHeader(insn);
+      insn->header.destreg_or_condmod = GEN_SFID_DATAPORT_DATA;
+
+      setSendsOperands(gen9_insn, GenRegister::null(), header, data);
+      gen9_insn->bits2.sends.src1_length = data_size;
+
+      const uint32_t msg_length = 1;
+      const uint32_t response_length = 0;
+      setMBlockRW(insn,
+                bti,
+                GEN75_P1_MEDIA_TYPED_BWRITE,
+                msg_length,
+                response_length);
+    }
+  }
 } /* End of the name space. */
diff --git a/backend/src/backend/gen9_encoder.hpp b/backend/src/backend/gen9_encoder.hpp
index d754d59..2eaa538 100644
--- a/backend/src/backend/gen9_encoder.hpp
+++ b/backend/src/backend/gen9_encoder.hpp
@@ -54,6 +54,8 @@ namespace gbe
     virtual void BYTE_SCATTER(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemSize, bool useSends);
     virtual unsigned setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
     virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum, bool useSends);
+    virtual void OBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t ow_size, bool useSends);
+    virtual void MBWRITE(GenRegister header, GenRegister data, uint32_t 
+ bti, uint32_t data_size, bool useSends);
   };
 }
 #endif /* __GBE_GEN9_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 10e2c9e..5f60ff3 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -3569,13 +3569,14 @@ namespace gbe
 
   void GenContext::emitOBWriteInstruction(const SelectionInstruction &insn) {
     const GenRegister header = ra->genReg(insn.src(0));
+    const GenRegister data = ra->genReg(insn.src(1));
     const uint32_t bti = insn.getbti();
     const uint32_t ow_size = insn.extra.elem;
     bool isA64 = bti == 255;
     if (isA64)
        p->OBWRITEA64(header, bti, ow_size);
     else
-       p->OBWRITE(header, bti, ow_size);
+       p->OBWRITE(header, data, bti, ow_size, insn.extra.splitSend);
   }
 
   void GenContext::emitMBReadInstruction(const SelectionInstruction &insn) { @@ -3587,8 +3588,9 @@ namespace gbe
 
   void GenContext::emitMBWriteInstruction(const SelectionInstruction &insn) {
     const GenRegister header = ra->genReg(insn.dst(0));
+    const GenRegister data = ra->genReg(insn.dst(1));
     const size_t data_size = insn.extra.elem;
-    p->MBWRITE(header, insn.getbti(), data_size);
+    p->MBWRITE(header, data, insn.getbti(), data_size, 
+ insn.extra.splitSend);
   }
 
   BVAR(OCL_OUTPUT_REG_ALLOC, false);
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index d95d03e..03ce0e2 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -1348,7 +1348,7 @@ namespace gbe
                 response_length);
   }
 
-  void GenEncoder::OBWRITE(GenRegister header, uint32_t bti, uint32_t ow_size) {
+  void GenEncoder::OBWRITE(GenRegister header, GenRegister data, 
+ uint32_t bti, uint32_t ow_size, bool useSends) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
     uint32_t sizeinreg = ow_size / 2;
     // half reg should also have size 1 @@ -1384,7 +1384,7 @@ namespace gbe
                 response_length);
   }
 
-  void GenEncoder::MBWRITE(GenRegister header, uint32_t bti, uint32_t data_size) {
+  void GenEncoder::MBWRITE(GenRegister header, GenRegister data, 
+ uint32_t bti, uint32_t data_size, bool useSends) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
     const uint32_t msg_length = 1 + data_size;
     const uint32_t response_length = 0; // Size of registers diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index 4e9fe58..3e45c81 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -297,11 +297,11 @@ namespace gbe
     /*! OBlock read */
     void OBREAD(GenRegister dst, GenRegister header, uint32_t bti, uint32_t ow_size);
     /*! OBlock write */
-    void OBWRITE(GenRegister header, uint32_t bti, uint32_t ow_size);
+    virtual void OBWRITE(GenRegister header, GenRegister data, uint32_t 
+ bti, uint32_t ow_size, bool useSends);
     /*! MBlock read */
     virtual void MBREAD(GenRegister dst, GenRegister header, uint32_t bti, uint32_t response_size);
     /*! MBlock write */
-    virtual void MBWRITE(GenRegister header, uint32_t bti, uint32_t data_size);
+    virtual void MBWRITE(GenRegister header, GenRegister data, uint32_t 
+ bti, uint32_t data_size, bool useSends);
     /*! A64 OBlock read */
     virtual void OBREADA64(GenRegister dst, GenRegister header, uint32_t bti, uint32_t ow_size);
     /*! A64 OBlock write */
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index dd21960..7990737 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -2324,18 +2324,33 @@ namespace gbe
                                   uint32_t bti,
                                   uint32_t ow_size) {
     SelectionInstruction *insn = this->appendInsn(SEL_OP_OBWRITE, 0, vec_size + 1);
-    SelectionVector *vector = this->appendVector();
     insn->src(0) = header;
     for (uint32_t i = 0; i < vec_size; ++i)
       insn->src(i + 1) = values[i];
     insn->setbti(bti);
     insn->extra.elem = ow_size; // number of OWord_size
 
-    // tmp regs for OWORD write header and values
-    vector->regNum = vec_size + 1;
-    vector->reg = &insn->src(0);
-    vector->offsetID = 0;
-    vector->isSrc = 1;
+    if (hasSends()) {
+      insn->extra.splitSend = 1;
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = 1;
+      vector->reg = &insn->src(0);
+      vector->offsetID = 0;
+      vector->isSrc = 1;
+
+      vector = this->appendVector();
+      vector->regNum = vec_size;
+      vector->reg = &insn->src(1);
+      vector->offsetID = 1;
+      vector->isSrc = 1;
+    } else {
+      // tmp regs for OWORD write header and values
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = vec_size + 1;
+      vector->reg = &insn->src(0);
+      vector->offsetID = 0;
+      vector->isSrc = 1;
+    }
 
   }
 
@@ -2366,18 +2381,33 @@ namespace gbe
                                   uint32_t bti,
                                   uint32_t data_size) {
     SelectionInstruction *insn = this->appendInsn(SEL_OP_MBWRITE, 0, 1 + tmp_size);
-    SelectionVector *vector = this->appendVector();
     insn->src(0) = header;
     for (uint32_t i = 0; i < tmp_size; ++i)
       insn->src(1 + i) = values[i];
     insn->setbti(bti);
     insn->extra.elem = data_size; // msg data part size
 
-    // We need to put the header and the data together
-    vector->regNum = 1 + tmp_size;
-    vector->reg = &insn->src(0);
-    vector->offsetID = 0;
-    vector->isSrc = 1;
+    if (hasSends()) {
+      insn->extra.splitSend = 1;
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = 1;
+      vector->reg = &insn->src(0);
+      vector->offsetID = 0;
+      vector->isSrc = 1;
+
+      vector = this->appendVector();
+      vector->regNum = tmp_size;
+      vector->reg = &insn->src(1);
+      vector->offsetID = 1;
+      vector->isSrc = 1;
+    } else {
+      // We need to put the header and the data together
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = 1 + tmp_size;
+      vector->reg = &insn->src(0);
+      vector->offsetID = 0;
+      vector->isSrc = 1;
+    }
   }
 
   // Boiler plate to initialize the selection library at c++ pre-main
--
1.9.1

_______________________________________________
Beignet mailing list
Beignet at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list