[Beignet] [PATCH] add sends for atomic operation, only for ocl 1.2

Guo, Yejun yejun.guo at intel.com
Wed Nov 30 04:33:52 UTC 2016


Signed-off-by: Guo, Yejun <yejun.guo at intel.com>
---
 backend/src/backend/gen8_encoder.cpp       |  2 +-
 backend/src/backend/gen8_encoder.hpp       |  2 +-
 backend/src/backend/gen9_encoder.cpp       | 26 ++++++++++++++++++++++++++
 backend/src/backend/gen9_encoder.hpp       |  1 +
 backend/src/backend/gen_context.cpp        | 20 ++++++++++++++------
 backend/src/backend/gen_encoder.cpp        |  4 ++--
 backend/src/backend/gen_encoder.hpp        |  2 +-
 backend/src/backend/gen_insn_selection.cpp | 26 +++++++++++++++++++++-----
 8 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/backend/src/backend/gen8_encoder.cpp b/backend/src/backend/gen8_encoder.cpp
index 8f73346..a29e59d 100644
--- a/backend/src/backend/gen8_encoder.cpp
+++ b/backend/src/backend/gen8_encoder.cpp
@@ -153,7 +153,7 @@ namespace gbe
     return gen8_insn->bits3.ud;
   }
 
-  void Gen8Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum) {
+  void Gen8Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister data, GenRegister bti, uint32_t srcNum) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
 
     this->setHeader(insn);
diff --git a/backend/src/backend/gen8_encoder.hpp b/backend/src/backend/gen8_encoder.hpp
index f6a91a0..1e8ce36 100644
--- a/backend/src/backend/gen8_encoder.hpp
+++ b/backend/src/backend/gen8_encoder.hpp
@@ -44,7 +44,7 @@ namespace gbe
     virtual void F16TO32(GenRegister dest, GenRegister src0);
     virtual void F32TO16(GenRegister dest, GenRegister src0);
     virtual void LOAD_INT64_IMM(GenRegister dest, GenRegister value);
-    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum);
+    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum);
     virtual void ATOMICA64(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum);
     virtual void UNTYPED_READ(GenRegister dst, GenRegister src, GenRegister bti, uint32_t elemNum);
     virtual void UNTYPED_WRITE(GenRegister src, GenRegister data, GenRegister bti, uint32_t elemNum);
diff --git a/backend/src/backend/gen9_encoder.cpp b/backend/src/backend/gen9_encoder.cpp
index b5be852..2d7e572 100644
--- a/backend/src/backend/gen9_encoder.cpp
+++ b/backend/src/backend/gen9_encoder.cpp
@@ -190,4 +190,30 @@ namespace gbe
         gen9_insn->bits2.sends.sel_reg32_desc = 1;
     }
   }
+
+  void Gen9Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum)
+  {
+    if (addr.reg() == data.reg())
+      Gen8Encoder::ATOMIC(dst, function, addr, data, bti, srcNum);
+    else {
+      GenNativeInstruction *insn = this->next(GEN_OPCODE_SENDS);
+      Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+      this->setHeader(insn);
+      insn->header.destreg_or_condmod = GEN_SFID_DATAPORT1_DATA;
+
+      setSendsOperands(gen9_insn, dst, addr, data);
+      if (this->curr.execWidth == 8)
+        gen9_insn->bits2.sends.src1_length = srcNum - 1;
+      else if (this->curr.execWidth == 16)
+        gen9_insn->bits2.sends.src1_length = 2 * (srcNum - 1);
+      else
+        assert(!"unsupported");
+
+      if (bti.file == GEN_IMMEDIATE_VALUE) {
+        gen9_insn->bits2.sends.sel_reg32_desc = 0;
+        setAtomicMessageDesc(insn, function, bti.value.ud, 1);
+      } else
+        gen9_insn->bits2.sends.sel_reg32_desc = 1;
+    }
+  }
 } /* End of the name space. */
diff --git a/backend/src/backend/gen9_encoder.hpp b/backend/src/backend/gen9_encoder.hpp
index 1c40b92..8b738cc 100644
--- a/backend/src/backend/gen9_encoder.hpp
+++ b/backend/src/backend/gen9_encoder.hpp
@@ -52,6 +52,7 @@ namespace gbe
     virtual unsigned setUntypedWriteSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemNum);
     virtual void BYTE_SCATTER(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemSize);
     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);
   };
 }
 #endif /* __GBE_GEN9_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 9505592..0a76209 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -1893,26 +1893,34 @@ namespace gbe
   }
 
   void GenContext::emitAtomicInstruction(const SelectionInstruction &insn) {
-    const GenRegister src = ra->genReg(insn.src(0));
+    const GenRegister addr = ra->genReg(insn.src(0));
     const GenRegister dst = ra->genReg(insn.dst(0));
     const uint32_t function = insn.extra.function;
     unsigned srcNum = insn.extra.elem;
 
+    GenRegister data = addr;
+    if (insn.extra.splitSend && srcNum > 1)
+      data = ra->genReg(insn.src(1));
+
     const GenRegister bti = ra->genReg(insn.src(srcNum));
 
     if (bti.file == GEN_IMMEDIATE_VALUE) {
-      p->ATOMIC(dst, function, src, bti, srcNum);
+      p->ATOMIC(dst, function, addr, data, bti, srcNum);
     } else {
       GenRegister flagTemp = ra->genReg(insn.dst(1));
       GenRegister btiTmp = ra->genReg(insn.dst(2));
 
-      unsigned desc = p->generateAtomicMessageDesc(function, 0, srcNum);
+      unsigned desc = 0;
+      if (insn.extra.splitSend)
+        desc = p->generateAtomicMessageDesc(function, 0, 1);
+      else
+        desc = p->generateAtomicMessageDesc(function, 0, srcNum);
 
       unsigned jip0 = beforeMessage(insn, bti, flagTemp, btiTmp, desc);
       p->push();
         p->curr.predicate = GEN_PREDICATE_NORMAL;
         p->curr.useFlag(insn.state.flag, insn.state.subFlag);
-        p->ATOMIC(dst, function, src, GenRegister::addr1(0), srcNum);
+        p->ATOMIC(dst, function, addr, data, GenRegister::addr1(0), srcNum);
       p->pop();
       afterMessage(insn, bti, flagTemp, btiTmp, jip0);
     }
@@ -2837,7 +2845,7 @@ namespace gbe
       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->ATOMIC(incRes, GEN_ATOMIC_OP_INC, sndMsg, sndMsg, GenRegister::immud(bti), 1);
     } p->pop();
 
     // Calculate the final addr
@@ -3503,7 +3511,7 @@ namespace gbe
         p->MOV(data, GenRegister::immud(insn.extra.printfSize + 12));
       } p->pop();
 
-      p->ATOMIC(addr, GEN_ATOMIC_OP_ADD, addr, GenRegister::immud(insn.extra.printfBTI), 2);
+      p->ATOMIC(addr, GEN_ATOMIC_OP_ADD, addr, addr, GenRegister::immud(insn.extra.printfBTI), 2);
       /* Write out the header. */
       p->MOV(data, GenRegister::immud(0xAABBCCDD));
       p->UNTYPED_WRITE(addr, addr, GenRegister::immud(insn.extra.printfBTI), 1);
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index 38161c2..2a03625 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -633,14 +633,14 @@ namespace gbe
     return 0;
   }
 
-  void GenEncoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum) {
+  void GenEncoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
 
     this->setHeader(insn);
     insn->header.destreg_or_condmod = GEN_SFID_DATAPORT_DATA;
 
     this->setDst(insn, GenRegister::uw16grf(dst.nr, 0));
-    this->setSrc0(insn, GenRegister::ud8grf(src.nr, 0));
+    this->setSrc0(insn, GenRegister::ud8grf(addr.nr, 0));
     if (bti.file == GEN_IMMEDIATE_VALUE) {
       this->setSrc1(insn, GenRegister::immud(0));
       setAtomicMessageDesc(insn, function, bti.value.ud, srcNum);
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index e5eb2e2..e2a24fe 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -171,7 +171,7 @@ namespace gbe
     /*! Wait instruction (used for the barrier) */
     void WAIT(uint32_t n = 0);
     /*! Atomic instructions */
-    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum);
+    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum);
     /*! AtomicA64 instructions */
     virtual void ATOMICA64(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum);
     /*! Untyped read (upto 4 channels) */
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 9722423..9fb6d55 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -1345,11 +1345,27 @@ namespace gbe
     insn->extra.function = function;
     insn->extra.elem = msgPayload;
 
-    SelectionVector *vector = this->appendVector();
-    vector->regNum = msgPayload; //bti not included in SelectionVector
-    vector->offsetID = 0;
-    vector->reg = &insn->src(0);
-    vector->isSrc = 1;
+    if (hasSends()) {
+      insn->extra.splitSend = 1;
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = 1;
+      vector->offsetID = 0;
+      vector->reg = &insn->src(0);
+      vector->isSrc = 1;
+      if (msgPayload > 1) {
+        vector = this->appendVector();
+        vector->regNum = msgPayload - 1;
+        vector->offsetID = 1;
+        vector->reg = &insn->src(1);
+        vector->isSrc = 1;
+      }
+    } else {
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = msgPayload; //bti not included in SelectionVector
+      vector->offsetID = 0;
+      vector->reg = &insn->src(0);
+      vector->isSrc = 1;
+    }
   }
 
   void Selection::Opaque::ATOMICA64(Reg dst, uint32_t function,
-- 
1.9.1



More information about the Beignet mailing list